JWT概念学习
JWT 全称 JSON Web Tokens ,是一个非常轻巧的规范。这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息。它的两大使用场景是:认证和数据交换。
1.什么是JSON Web令牌?
- JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对对JWT进行签名。
- 尽管可以对JWT进行加密以在双方之间提供保密性,但我们将重点关注已签名的令牌。签名的令牌可以验证其中包含的声明的完整性,而加密的令牌则将这些声明隐藏在其他方的面前。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。
-
基于传统的token认证
用户登录,服务端给返回token,并将token保存在服务端。
以后用户再来访问时,需要携带token,服务端获取token后,再去数据库获取token进行校验
-
JWT
用户登录,服务端给用户返回一个token(服务端不保存)
以后用户再来访问,需要携带token,服务端获取token后,
再做token的校验。
优势:相比较传统的token相比,它无需在服务端保存token。
2.什么时候应该使用JSON Web令牌?
以下是JSON Web令牌有用的一些情况:
- 授权:这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。json web token ,一般用于用户认证(前后端分离/微信小程序/app开发)
- 信息交换:JSON Web令牌是在各方之间安全地传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确定发件人是他们所说的人。另外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。
3.jwt实现过程
- 用户提交用户名和密码给服务端,如果登录成功,使用jwt创建一个token,并给用户返回。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
注意:jwt生成的token是由三段字符串组成,并且拼接起来。
-
第一段字符串,HEADER头,内部包含算法/token类型。
json转化为字符串,然后做basee64url加密(base64加密;替换±)
{
"alg": "HS256",
"typ": "JWT"
}
-
第二段字符串,payload有效载荷,自定义值(你想给用户返回的信息)
json转化为字符串,然后base64url加密(base64加密;+_)
请注意,对于已签名的令牌,此信息尽管可以防止篡改,但任何人都可以读取。除非将其加密,否则请勿将机密信息放入JWT的有效负载或报头元素中。
{
"id": "1234",
"name": "John Doe",
"exp": 1516239022 #超时时间
}
- 第三部分字符串:签名
第一步:第1,2部分密文拼接起来
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
第二步:对前2部分密文进行HS256加密 + 加盐
第三步:对HS256加密后的密文再做base64url加密
-
以后用户再来访问时候,需要携带token,后端需要对token进行校验
- 获取token
- 第一步:对token进行切割
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- 第二步:对第二段进行base64Url进行解密,并获取payload信息,检测token是否已经超时?
{ "id": "1234", "name": "John Doe", "exp": 1516239022 #超时时间 }
- 第三步:把1,2端拼接,再次执行HS256加密(哈希不能反解)
第一步:第1,2部分密文拼接起来
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
第二步:对前2部分密文进行HS256加密 + 加盐
密文 = base64解密(SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c)
如果相等,表示token未被修改过(认证通过)
4.优缺点
- JWT的优点:
- 无需再服务端存储用户数据,减轻服务端压力
- 轻量级,json风格,比较简单
- 跨语言
- JWT的缺点:
- token一旦签发,无法修改
- 无法更新token有效期,用户登录状态刷新难以实现
- 无法销毁一个token,服务端不能对用户状态进行绝对控制
- 不包含权限控制
5.面试相关
1 .你们使用JWT做登录凭证,如何解决token注销问题(比如app登录之后)
答:jwt的缺陷是token生成后无法修改,因此无法让token失效。只能采用其它方案来弥补,基本思路如下:
方案一:
1)适当减短token有效期,让token尽快失效
2)删除客户端cookie
3)服务端对失效token进行标记,形成黑名单,虽然有违无状态特性,但是因为token有效期短,因此标记 时间也比较短。服务器压力会比较小
方案二:
1)用户登录后,生成JWT
2)把JWT的id存入redis,只有redis中有id的JWT,才是有效的JWT
3)退出登录时,把ID从Redis删除即可
2.既然token有效期短,怎么解决token失效后的续签问题?(app登录之后续签怎么解决,app如何保持一次登陆后持续保持)
答:在验证用户登录状态的代码中,添加一段逻辑:判断cookie即将到期时,重新生成一个token。比如token有效期为30分钟,当用户请求我们时,我们可以判断如果用户的token有效期还剩下10分钟,那么就重新生成token。因此用户只要在操作我们的网站,就会续签token
3.如何解决异地登录问题?
答:JWT设计为了实现无状态的登录,因此token无法修改,难以实现异地登录的判断,或者强制让登录token失效。
因此如果有类似需求, 就不应选择JWT作为登录方案,而是使用传统session登录方案。
但是,如果一定要用JWT实现类似要过,就需要在Redis中记录登录用户的JWT的token信息,这样就成了有状态的登录,还不如一开始就选择Session方案。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端