jwt和oauth2的原理、特点、区别及使用场景
JWT是一种认证协议,提供了一种用于发布接入令牌(Access Token),并对发布的签名接入令牌进行验证的方法。SSO私钥加密token。应用端公钥解密token,
OAuth2.0是一种授权框架,提供了一套详细的授权机制(指导)。用户或应用可以通过公开的或私有的设置,授权第三方应用访问特定资源。
一、OAuth2认证
OAuth2是一个关于授权的开放标准,核心思路是通过各类认证手段(具体什么手段OAuth2不关心)认证用户身份,并颁发token(令牌),
使得第三方应用可以使用该token(令牌)在限定时间、限定范围访问指定资源。

OAuth2相关概念:
资源所有者(resources owner):拥有被访问资源的用户
客户端/第三方应用(client):第三方应用,获取资源服务器提供的资源
授权服务器(authorization server):认证服务器,提供授权许可code、令牌token等
资源服务器(resource server):资源服务器,拥有被访问资源的服务器,需要通过token来确定是否有权限访问
OAuth2几种模式:
获取令牌的方式主要有四种,分别是授权码模式、隐式授权码模式(简单模式)、密码模式和客户端模式。
1)授权码模式(authorization code)
这种模式是最安全的OAuth2的授权模式。设计了auth code,通过这个code再获取token,最后通过token获取资源。支持refresh token。



应用场景:
各大应用内的qq,微信,微博登录等。比如某应用内的qq登录,过程如下:
a.用户点击qq登录,会先跳转到qq登录页面,这时请求已经跳转到qq服务器了,然后用户输入账号或者扫码登录,这时所有请求都在qq服务器完成。
b.用户正确登录后,qq服务器返回用户的code给第三方应用,然后第三方应用再使用code去授权服务器请求获取token。(这一步用户不可见)
c.第三方应用获取到token后,再使用token获取用户的qq名称,头像等信息。
优缺点:
优点:用户可以控制自身的一些权限是否给第三方,第三方只能获取到用户临时产生的一个访问的code,安全性。
缺点:认证过程繁琐。
2)隐式授权码模式/简单模式(implicit)
和授权码模式类似,只不过少了获取code的步骤,是直接获取令牌token的,适用于公开的浏览器单页应用,令牌直接从授权服务器返回,不支持刷新令牌,且没有code安全保证,令牌容易因为被拦截窃听而泄露。
不支持refresh token
3)密码模式(resource owner password credentials)
这种模式是最不推荐的,因为client可能存了用户密码
这种模式主要用来做遗留项目升级为oauth2的适配方案
当然如果client是自家的应用,也是可以
支持refresh token
4)客户端模式(client credentials)
这种模式直接根据client的id和密钥即可获取token,无需用户参与
这种模式比较合适消费api的后端服务,比如拉取一组用户信息等
不支持refresh token,主要是没有必要
二、JWT机制
JWT工作原理:
JWT的工作流程如下:
- 用户登录:用户在客户端输入登录信息,并将这些信息发送到服务器。
- 生成JWT:服务器接收到用户的登录信息后,验证其合法性。如果合法,服务器会使用私钥对用户信息进行加密,生成一个 JWT。这个 JWT 中包含了用户的身份信息和一些额外的数据。
- 发送JWT:生成的 JWT 会被发送回客户端,通常是在登录成功的响应中。
- 存储JWT:客户端收到 JWT 后,将其存储在本地,以便在后续请求中使用。
- 发送请求:每当客户端需要向服务器发送请求时,会将存储的 JWT 加入到请求的头部中进行身份认证。
- 验证JWT:服务器在处理请求时,会从请求中提取 JWT,并使用公钥对其进行验证。验证的过程会检查 JWT 是否有效(例如,是否过期)以及其内容是否被篡改。
- 处理请求:如果 JWT 验证通过,服务器会根据 JWT 中的信息进行身份验证和授权,处理请求并返回相应的结果。
- 客户端响应:客户端根据服务器的响应进行相应的操作,比如更新界面、显示消息等。
Signature是使用指定算法对Header和Payload进行签名生成的,用于验证JWT的完整性和真实性。Signature的生成方式通常是将Header和Payload连接起来然后使用指定算法对其进行签名,最终将签名结果与Header和Payload一起组成JWT。
Signature的生成和验证需要使用相同的密钥,下面是一个示例Signature:
Signature = HMACSHA256(base64UrlEncode(header) + "."+base64UrlEncode(payload),secret)
- HMACSHA256 是使用 HMAC SHA256 算法进行签名
- header和payload需要经过Base64编码,secret是用于签名和验证的密钥
- 最后将Signature经过Base64编码与Header、Payload的Base64编码用句点(.)分隔就形成了一个完整的JWT。

JWT概念:
JWT全称为Json Web Token,随着微服务架构的流行而越来越火,号称新一代的认证技术。
OAuth2中使用token验证用户登录合法性,但token最大的问题是不携带用户信息,资源服务器无法在本地进行验证,每次对于资源的访问,资源服务器都需要向认证服务器发起请求,一是验证token的有效性,二是获取token对应的用户信息。如果有大量的此类请求,无疑处理效率是很低,且认证服务器会变成一个中心节点,这在分布式架构下很影响性能。
JWT就是在这样的背景下诞生的,从本质上来说,jwt和OAuth2没有可比性。普通的oauth2颁发的就是一串随机hash字符串,本身无意义,而jwt使用一种特殊格式的token,token是有特定含义的,分为三部分:
-头部Header
-载荷Payload
-签名Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
这三部分均用base64进行编码,并使用.进行分隔。一个典型的jwt格式的token类似xxxxx.yyyyy.zzzzz。
jwt其实并不是什么高深莫测的技术,相反非常简单。认证服务器通过对称或非对称的加密方式利用payload生成signature,并在header中申明签名方式,仅此而已。通过这种本质上极其传统的方式,jwt可以实现分布式的token验证功能,即资源服务器通过事先维护好的对称或者非对称密钥(非对称的话就是认证服务器提供的公钥),直接在本地验证token,这种去中心化的验证机制非常适合分布式架构。jwt相对于传统的token来说,解决以下两个痛点:
1、通过验证签名,对于token的验证可以直接在资源服务器本地完成,不需要连接认证服务器;
2、在payload中可以包含用户相关信息,这样就轻松实现了token和用户信息的绑定;
如果认证服务器颁发的是jwt格式的token,那么资源服务器就可以直接自己验证token的有效性并绑定用户,这无疑大大提升了处理效率且减少了单点隐患。
JWT真正的好处是让颁发JWT token的认证服务器和校验JWT token的应用服务器可以完全分开。
公式如下:
签名: Signature=SHA-256(Base64Url(Header)+Base64Url(Payload ),密钥),jwt=Base64Url(Header) .Base64Url(Payload ). Base64Url(Signature)
验签: Header+Payload进行SHA-256哈希;使用公钥签名Signature进行解密,解密后的值和前面哈希值对比。
RSA的两点基本原理
私钥加密,持有私钥或公钥才可以解密
公钥加密,持有私钥才可解密
RSA公钥、私钥加密的使用场景
公钥和私钥都可以用于加解密操作,用公钥加密的数据只能由对应的私钥解密,反之亦然。虽说两者都可用于加密,但是不同场景使用不同的密钥来加密,规则如下:
1、私钥用于签名、公钥用于验签
签名和加密作用不同,签名并不是为了保密,而是为了保证这个签名是由特定的某个人签名的,而不是被其它人伪造的签名,所以私钥的私有性就适合用在签名用途上。
私钥签名后,只能由对应的公钥解密,公钥又是公开的(很多人可持有),所以这些人拿着公钥来解密,解密成功后就能判断出是持有私钥的人做的签名,验证了身份合法性。
2、公钥用于加密、私钥用于解密,这才能起到加密作用
因为公钥是公开的,很多人可以持有公钥。若用私钥加密,那所有持有公钥的人都可以进行解密,这是不安全的!
若用公钥加密,那只能由私钥解密,而私钥是私有不公开的,只能由特定的私钥持有人解密,保证的数据的安全性。
适用场景:
一次性的身份认证、api的鉴权等,这些场景能充分发挥jwt无状态以及分布式验证的优势。
不适用的场景:
不要试图用jwt去代替session。这种模式下其实传统的session+cookie机制工作的更好,jwt因为其无状态和分布式,事实上只要在有效期内,是无法作废的,用户的签退更多是一个客户端的签退,服务端token仍然有效,你只要使用这个token,仍然可以登陆系统。另外一个问题是续签问题,使用token,无疑令续签变得十分麻烦,当然你也可以通过redis去记录token状态,并在用户访问后更新这个状态,但这就是硬生生把jwt的无状态搞成有状态了,而这些在传统的session+cookie机制中都是不需要去考虑的。
三 应用场景
- OAuth2用在使用第三方账号登录的情况(比如使用weibo, qq, github登录某个app)
- JWT是用在前后端分离, 需要简单的对后台API进行保护时使用.(前后端分离无session, 频繁传用户密码不安全)
部分原文引用:https://www.cnblogs.com/alan6/p/12335416.html
搭建授权服务 -参考
https://www.cnblogs.com/fp2952/p/8973613.html
https://cloud.tencent.com/developer/tools/blog-entry?target=https%3A%2F%2Fwww.cnblogs.com%2Ffp2952%2Fp%2F9193959.html&objectId=1497573&objectType=1&contentType=undefined

浙公网安备 33010602011771号