JWT和OAuth2.0

前言

JWT和OAuth2.0没有可比性,是两个完全不同的东西。

JWT是一种认证协议,提供了一种用于发布接入令牌(Access Token),并对发布的签名接入令牌进行验证的方法。SSO私钥加密token。应用端公钥解密token,

OAuth2.0是一种授权框架,提供了一套详细的授权机制(指导)。用户或应用可以通过公开的或私有的设置,授权第三方应用访问特定资源。

一、JWT

1、JWT格式

一个JWT包含3个部分:

头部Header:可存放签名的类型

数据Payload:可存放用户数据和有效期,Payload的内容在接收者端是通过签名(Signature)来校验的。

签名Signature:使用密钥对Header和Payload数据进行加密生成签名。

JWT为了便于http传输,3个部分需再进行Base64Url编码后用.进行关联,格式如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

JWT真正的好处是让颁发JWT token的认证服务器和校验JWT token的应用服务器可以完全分开。

那签名是如何完成认证功能的呢,且看:

  1. 用户向认证服务器提交用户名和密码,认证服务器也可以和应用服务器部署在一起,但往往是独立的居多;
  2. 认证服务器校验用户名和密码组合,然后创建一个JWT token,token的Payload里面包含用户的身份信息,以及过期时间戳;
  3. 认证服务器使用密钥对Header和Payload进行签名,然后发送给客户浏览器;
  4. 浏览器获取到经过签名的JWT token,然后在之后的每个HTTP请求中附带着发送给应用服务器。经过签名的JWT就像一个临时的用户凭证,代替了用户名和密码组合,之后都是JWT token和应用服务器打交道了;
  5. 应用服务器检查JWT签名,确认Payload确实是由密钥拥有者签过名的;
  6. Payload身份信息代表了某个用户;
  7. 只有认证服务器拥有私钥,并且认证服务器只把token发给提供了正确密码的用户;
  8. 因此应用服务器可以认为这个token是由认证服务器颁发的也是安全的,因为该用户具有了正确的密码;
  9. 应用服务器继续完成HTTP请求,并认为这些请求确实属于这个用户;

2、签名和验签

对于JWT,签名方式有很多种,这里我们主要了解HS256和RS256。

HS256

HS256 使用同一个「secret_key」进行签名与验证(对称加密)。一旦 secret_key 泄漏,就毫无安全性可言了。

  • 如何使用哈希函数生成签名?

我们拿到Header、Payload外,还要加上一个密码,将这三个输入值一起哈希。输出结果是一个SHA-256 HMAC或者基于哈希的MAC。如果需要重复生成,则需要同时拥有Header、Payload和密码才可以。这也意味着,哈希函数的输出结果是一个数字签名,因为输出结果就表示了Payload是由拥有密码的角色生成并加签了的,没有其它方式可以生成这样的输出值了。

  • 如何校验JWT签名?

当我们的服务接收到HS256签名的JWT时,我们需要使用同样的密码才能校验并确认token里面的Payload是否有效。为了验证签名,我们只需要将JWT Header和Payload以及密码通过哈希函数生成结果。JWT的接收者需要拿到和发送者一样的密码值。如果我们得到的哈希结果和JWT第三部分的签名值是一致的,则说明有效,可以确认发送者确实和接收者拥有相同的密码值。

  • 公式如下:

签名Signature=Header+Payload+一个密码 进行SHA-256哈希;再进行Base64Url编码(主要方便url上传输)。

验签: Header+Payload+一个密码 进行SHA-256哈希;和JWT的签名Signature对比。

RS256

RS256 是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。相比HS256更加安全。

使用RS256我们同样需要生成一个MAC,其目的仍然是创建一个数字签名来证明一个JWT的有效性。只是在这种签名方式中,我们将创建token和校验token的能力分开,只有认证服务器具备创建的能力,而应用服务器,具备校验的能力。

这样,我们需要创建两个密钥而不是一个:

仍然需要一个私钥,不过这次它只能被认证服务器拥有,只用来签名JWT。
私钥只能用来签名JWT,不能用来校验它。
第二个密钥叫做公钥(public key),是应用服务器使用来校验JWT。
公钥可以用来校验JWT,但不能用来给JWT签名。
公钥一般不需要严密保管,因为即便黑客拿到了,也无法使用它来伪造签名。

  • 公式如下:

签名Signature=Header+Payload 进行SHA-256哈希,再使用私钥对哈希值进行签名;再进行Base64Url编码(主要方便url上传输)。

验签: Header+Payload进行SHA-256哈希;使用公钥签名Signature进行解密,解密后的值和前面哈希值对比。

RSA的两点基本原理
  1. 私钥加密,持有私钥或公钥才可以解密
  2. 公钥加密,持有私钥才可解密
RSA公钥、私钥加密的使用场景

公钥和私钥都可以用于加解密操作,用公钥加密的数据只能由对应的私钥解密,反之亦然。虽说两者都可用于加密,但是不同场景使用不同的密钥来加密,规则如下:

1、私钥用于签名、公钥用于验签

签名和加密作用不同,签名并不是为了保密,而是为了保证这个签名是由特定的某个人签名的,而不是被其它人伪造的签名,所以私钥的私有性就适合用在签名用途上。

私钥签名后,只能由对应的公钥解密,公钥又是公开的(很多人可持有),所以这些人拿着公钥来解密,解密成功后就能判断出是持有私钥的人做的签名,验证了身份合法性。

2、公钥用于加密、私钥用于解密,这才能起到加密作用

因为公钥是公开的,很多人可以持有公钥。若用私钥加密,那所有持有公钥的人都可以进行解密,这是不安全的!

若用公钥加密,那只能由私钥解密,而私钥是私有不公开的,只能由特定的私钥持有人解密,保证的数据的安全性。

二、OAuth2.0

OAuth2 有4种授权模式, 其中的access code授权码模式在实现时可以使用JWT生成code, 也可以不用. 它们之间没有必然的联系;

  • 示例1:QQ音乐使用微信登录
    在这里插入图片描述

  • 示例2:口碑使用支付宝登录
    在这里插入图片描述

三、应用场景

  1. OAuth2用在使用第三方账号登录的情况(比如使用weibo, qq, github登录某个app)
  2. JWT是用在前后端分离, 需要简单的对后台API进行保护时使用.(前后端分离无session, 频繁传用户密码不安全)
<think>我们参考了用户提供的引用资料,特别是引用[1]引用[2],其中明确指出了JWTOAuth2.0区别与联系。同时,结合引用[4]中的实际应用场景,我们可以更清晰地解释这两者的关系。###区别与联系分析1.**本质区别**:-**OAuth2.0**是一个**授权框架**(AuthorizationFramework),它解决的是如何让一个应用(第三方应用)在用户授权的前提下访问用户在另一个服务(如微信、支付宝)上的资源,而无需用户提供账号密码。它的核心是颁发**访问令牌(AccessToken)**,这个令牌代表用户授予的权限范围[^1][^2]。-**JWT(JSONWebToken)**是一种**令牌格式**(TokenFormat),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息。这些信息可以被验证信任,因为它是数字签名的。JWT本身并不关心令牌是如何颁发的,它只定义令牌的结构验证方式[^1][^2]。2.**联系**:-**结合使用**:在实际应用中,OAuth2.0框架颁发的访问令牌(AccessToken)可以采用JWT格式。这样,访问令牌就具有自包含性(包含用户信息、权限范围等),并且可以通过签名验证其真实性,无需每次验证都查询数据库。这种组合在现代Web应用API中非常常见[^1][^3]。-**使用场景互补**:-**OAuth2.0**常用于**第三方授权登录**(如使用微信登录某个App)或**API访问授权**(如第三方应用访问用户存储在云服务上的文件)[^4]。-**JWT**常用于**无状态的用户认证**(如前后端分离架构中,用户登录后服务器生成一个JWT,客户端在后续请求中携带该JWT来证明身份)[^2][^4]。3.**功能对比**:|特性|OAuth2.0|JWT||---------------|-----------------------------------|----------------------------------||**定位**|授权框架|令牌格式标准||**核心目标**|解决第三方应用访问用户资源的问题|安全传输声明信息||**令牌类型**|定义了访问令牌、刷新令牌等概念|是一种具体的令牌格式||**依赖关系**|不依赖特定令牌格式(可用JWT或其他)|可独立使用,也可作为OAuth的令牌||**典型场景**|社交登录、API授权|无状态认证、信息交换|###实际应用示例-**OAuth2.0流程**(以微信登录为例):1.用户点击“微信登录”。2.应用重定向用户到微信授权页面。3.用户同意授权。4.微信重定向回应用,并附带授权码(code)。5.应用用授权码向微信换取访问令牌(AccessToken)。6.应用使用访问令牌获取用户基本信息(如昵称、头像)。7.应用建立自己的用户会话(如生成JWT作为本地会话)。-**JWT在认证中的应用**:-用户使用用户名密码登录,服务器验证后生成JWT(包含用户ID、过期时间等)。-客户端存储JWT(如localStorage),并在后续请求的`Authorization`头中携带。-服务器验证JWT签名有效期,无需查库即可确认用户身份。###选择建议-当你的应用需要**允许用户使用第三方账号(如微信、支付宝)登录**时,应选择**OAuth2.0**。-当你的应用是**前后端分离架构**且需要**简单的用户认证机制**(避免使用Session)时,可选择**JWT**作为认证令牌。-两者可结合:在OAuth2.0流程中,用JWT格式颁发访问令牌,兼顾授权高效验证[^1][^3]。###代码示例:JWT生成与验证(Python)```pythonimportjwtfromdatetimeimportdatetime,timedeltaSECRET_KEY="your-256-bit-secret"#实际应用中应使用强密钥defcreate_jwt(user_id:int)->str:payload={"sub":user_id,#主题(用户ID)"exp":datetime.utcnow()+timedelta(hours=1),#过期时间"iat":datetime.utcnow()#签发时间}returnjwt.encode(payload,SECRET_KEY,algorithm="HS256")defverify_jwt(token:str)->dict:try:payload=jwt.decode(token,SECRET_KEY,algorithms=["HS256"])return{"user_id":payload["sub"],"valid":True}exceptjwt.ExpiredSignatureError:return{"error":"Tokenexpired","valid":False}exceptjwt.InvalidTokenError:return{"error":"Invalidtoken","valid":False}#测试token=create_jwt(123)print("JWT:",token)result=verify_jwt(token)print("验证结果:",result)```###总结-**区别**:OAuth2.0是授权框架,JWT是令牌格式。-**联系**:OAuth2.0可以使用JWT作为其访问令牌的格式,两者协同工作。-**选择**:根据场景需求(第三方登录vs本地无状态认证)选择使用,或组合使用。§§相关问题§§1.如何在OAuth2.0流程中使用JWT作为访问令牌?2.JWT令牌的安全性如何保障(如防止泄露、篡改)?3.OAuth2.0的授权码模式(AuthorizationCodeFlow)具体步骤是什么?</think>### JWTOAuth 2.0区别与联系 #### 核心区别 | 特性 | JWT (JSON Web Token) | OAuth 2.0 | |--------------|---------------------------------------|------------------------------------| | **本质** | **令牌格式标准** | **授权框架** | | **主要功能** | 安全传输声明信息 | 管理第三方应用访问资源的授权流程 | | **依赖关系** | 可独立使用 | 依赖令牌(如JWT)实现具体功能 | | **场景定位** | 认证/信息交换 | 授权委托 | | **令牌类型** | 自包含结构化令牌 | 定义获取令牌的流程,不限定令牌格式 | #### 具体差异分析 1. **功能定位不同** - JWT 是轻量级的**信息容器**,用于安全传输声明(如用户ID、权限),其签名机制保证数据完整性来源验证[^1][^2] - OAuth 2.0 是**授权协议**,解决"如何让第三方应用在用户授权下访问资源服务器"的问题,例如微信登录淘宝[^4] 2. **技术实现差异** - JWT 包含三部分:`Header.Payload.Signature`,例如: $$ \text{eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c} $$ - OAuth 2.0 定义四种授权流程:授权码模式、隐式模式、密码模式、客户端凭证模式[^3] 3. **应用场景区别** | 场景 | 推荐方案 | 说明 | |---------------------|---------------|-------------------------------| | 前后端分离认证 | ✅ JWT | 无状态会话管理 | | 第三方登录(微信/支付宝) | ✅ OAuth 2.0 | 委托授权[^4] | | API访问控制 | 🟡 两者结合 | OAuth定义流程 + JWT作为令牌 | #### 核心联系 1. **协同工作模式** OAuth 2.0 常使用 JWT 作为**访问令牌(Access Token)** 的承载格式: ```mermaid graph LR A[用户] -->|授权请求| B(OAuth 2.0 服务) B -->|颁发JWT令牌| C[第三方应用] C -->|携带JWT访问| D[资源服务器] D -->|验证JWT签名| E[返回受保护资源] ``` 2. **优势互补** - JWTOAuth 提供**自验证令牌**:资源服务器无需查询授权服务器即可验证令牌有效性[^1] - OAuthJWT 提供**标准化授权流程**:包括令牌刷新、作用域控制等能力[^3] 3. **安全增强** 结合使用时形成双重保护: - OAuth 控制**是否发放令牌** - JWT 保证令牌**内容不可篡改** $$ \text{安全性} = \text{OAuth流程控制} + \text{JWT签名验证} $$ #### 典型结合案例 Spring Security 整合方案: ```java @Configuration @EnableAuthorizationServer public class OAuth2Config extends AuthorizationServerConfigurerAdapter { @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("clientapp") .secret("{noop}123456") .authorizedGrantTypes("authorization_code") .scopes("read_profile"); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey("mySecretKey"); // JWT签名密钥 return converter; } } ``` *此配置使OAuth 2.0服务颁发JWT格式的访问令牌[^3]* ### 选择建议 - 需实现**第三方登录/API开放平台** → 选择 OAuth 2.0 - 需**前后端无状态认证** → 选择 JWT - **高安全要求系统** → 组合使用(OAuth 2.0流程 + JWT令牌) > **关键洞察**:JWT是"信息包装箱",OAuth 2.0是"物流管理系统"——前者解决内容安全问题,后者解决运输流程问题[^1][^2]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值