JWT的使用

jwt最致命的弱点:无法自己续期和指定失效。

1.什么是JWT?

JSON Web Token,通过数字签名的方式,用json对象为载体,在不同的服务端之间安全的传输信息。

2.JWT有什么用?

最常用的是授权认证,确保安全,一旦用户登录,后续每个请求都将包含JWT,系统在每次处理用户请求之前,都要先进行JWT安全校验,校验通过之后才能进行后续操作。

3.JWT的优点?

负载中包含了所有用户所需要的信息,避免了多次查询数据库。

脱离数据库,不改变数据库中的内容,不需要在服务端保存会话信息,只是在代码的实体类加入token字段。

因为 Token是以 JSON 加密的形式保存在客户端的,所以 JWT是跨语言的,原则上任何 web 形式都支持。

4.JWT的组成?

三段:header.payload.Signature

header:头部 (标题包含了令牌的元数据,并且包含签名和 / 或加密算法的类型):承载两部分信息:token 类型和采用的加密算法。

payload:负载 (类似于飞机上承载的物品)

有效信息包含三个部分
1. 标准中注册的声明
                    iss: jwt 签发者
                    sub: 面向的用户 (jwt 所面向的用户)
                    aud: 接收 jwt 的一方
                    exp: 过期时间戳 (jwt 的过期时间,这个过期时间必须要大于签发时间)
                    nbf: 定义在什么时间之前,该 jwt 都是不可用的.
                    iat: jwt 的签发时间
                    jti: jwt 的唯一身份标识,主要用来作为一次性 token, 从而回避重放攻击。
2. 公共的声明
					一般添加用户的相关信息或其他业务需要的必要信息,但不能添加私密信息,因为该部分可以在用户端解密。
3. 私有的声明
					提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为 base64 是对称解密的,意味着该部分信息可以归类为明文信息。

Signature: 签名 / 签证

签证信息由这三部分组成:
header (base64 后的)
payload (base64 后的)
secret
这个部分需要 base64 加密后的 header 和 base64 加密后的 payload 使用. 连接组成的字符串,然后通过 header 中声明的加密方式进行加盐 secret 组合加密,然后就构成了 jwt 的第三部分。
密钥 secret 是保存在服务端的,服务端会根据这个密钥进行生成 token 和进行验证,所以需要保护好。
5.JWT的前后端认证流程?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ajJBxnGH-1663231510234)(E:\mzxstudy\一些知识点\jwt流程.jpeg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r1ysxgkt-1663231510235)(E:\mzxstudy\一些知识点\jwt流程2.PNG)]

6.token的有效性?

有效时间是指签发的 token 仅在 ttl 时间(单个签发的token有效期)内可以用来正常使用 (鉴权,获取用户信息等操作),过了这个有效时间后,改 token 将被废弃,放入黑名单,路由中间件鉴权也将会失败。

刷新时间是指在 refresh_ttl 时间内,你可以使用之前签发的 token (此时已经失效了) 来换取一个新的 token,新的 token 的有效时间还是 ttl。后续的鉴权验证需要使用新的 token 才能正常通过。

用之前即将过期的 token 换取新的 token,以此重复,直到 refresh_ttl 之后,整个流程将会失效,旧的 token 不在支持换取新的 token,必须执行用户登录操作才能签发新的 token。

7.后端认证需要做哪些事?
引入依赖
实体类加token字段
控制器写登录部分:先登录成功,再添加token,存储在 localStorage 和 Vuex 里
前端每次路由跳转,判断 localStorage 有无 token ,没有则跳转到登录页,有则请求获取用户信息,改变登录状态;
每次请求接口,在 Axios 请求头里携带 token;
后端接口判断请求头有无 token,没有或者 token 过期,返回401;
前端得到 401 状态码,重定向到登录页面
JWTutil工具类的添加:包含有效期,签名,创建token
在每一个页面之间登录都要验证token的处理
写token验证的拦截器(这个也可以是前端做)

一些问题的解决方式:
1.vue和Spring boot的跨域问题?前后端解决的优缺点:https://zhuanlan.zhihu.com/p/419492588

前端解决方法:引入axios请求,开启写入凭证,withCredentials等于true,设置统一请求路径,封装到axios.defaults.baseURL中,设置统一访问路径,配置跨域代理。

优缺点:写入的东西有点多,看起来有点麻烦。

后端解决方法:在springboot框架的后端想要解决跨域问题,只需要添加一个类CorsConfig,并且让它实现WebMvcConfigurer接口

优缺点:简单,一般有已经完成的代码,只需复制即可用。

2.解决token在用户登出之后还有效的问题?

这个用redis解决之后就相当于在后端中也使用了数据库的功能,跟session的方案差不多了,并且用uuid的方案和JWT也差不多,原始的token就是一个uuid。

但是因为jwt包含部分业务信息,减少了token验证的交互,效率更高一点。

解决方案:https://juejin.cn/post/6932702419344162823

3.token在前端存在本地会话(local storage)或者cookie里有什么不一样?

LocalStorage显而易见的好处是不会每次都发回服务器,可以减少HTTP请求和响应的大小,当然坏处就是需要显示的写代码回传服务器。

如果大部分资源/请求都需要服务器授权,那就应该用Cookie,浏览器会自动将Cookie发给服务器。如果绝大部分资源都不需要授权,只有少数几个功能(AJAX实现)是需要授权的,那么LocalStorage也不错。

建议将JWT存到httponly cookie中,优点是不需要在JavaScript代码中处理token,后续请求会自动跟上token信息的cookie。

4.JWT中数字签名的作用?

防止内容被篡改。

因为jwt是由服务端生成并发放的,其中签名是由服务端的私钥加密而成的,只要保证了私钥的安全,就能保证签名是安全的。

JWT的好处:1. 就是一种Cookie-Session改造版的具体实现
2.可以不用在服务端存储认证信息(比如 token),完全由客户端提供,服务端只要根据 JWT 自身提供的解密算法就可以验证用户合法性,而且这个过程是安全的。
3.对数据库无压力。
2.可以不用在服务端存储认证信息(比如 token),完全由客户端提供,服务端只要根据 JWT 自身提供的解密算法就可以验证用户合法性,而且这个过程是安全的。
3.对数据库无压力。
4.要注意合理的设置过期时间,不要太长
### JWT 使用教程详解 #### 1. JWT 基础概念 JSON Web Token (JWT) 是一种开放标准 RFC 7519,用于在网络应用环境间安全地传输信息[^1]。它是一个紧凑且自包含的字符串,能够传递声明(Claims),这些声明通常被用来在各方之间传达身份验证和其他用户相关信息。 JWT 的主要组成部分包括三部分:Header、Payload 和 Signature。每一部分都通过 Base64Url 编码并用点号 `.` 进行分隔[^1]。 #### 2. JWT 结构分析 - **Header**: 描述令牌元数据,通常是加密算法的信息。 - **Payload**: 存储实际的数据或声明,可以分为注册声明(Registered Claims)、公共声明(Public Claims)和私有声明(Private Claims)。 - **Signature**: 通过对前两部分进行签名来确保数据未被篡改。 具体生成过程如下: ```plaintext token = base64urlEncode(header) + "." + base64urlEncode(payload) + "." + HMACSHA256(base64urlEncode(header) + "." + base64urlEncode(payload), secretKey) ``` #### 3. 工作原理 当客户端向服务器发送请求时,可以通过 HTTP 头部字段中的 `Authorization` 来携带 JWT。例如: ```http GET /api/resource HTTP/1.1 Host: example.com Authorization: Bearer <token> ``` 服务器接收到此请求后会解析并验证该令牌的有效性和合法性。 #### 4. 实现方式举例 ##### Python 中的实现 Python 可以利用 PyJWT 库轻松完成 JWT 的编码与解码操作。下面展示了一个简单的例子[^4]: ```python import jwt from datetime import datetime, timedelta def create_jwt_token(secret_key="your_secret", algorithm="HS256"): payload = { "sub": "1234567890", "name": "John Doe", "iat": int(datetime.utcnow().timestamp()), "exp": int((datetime.utcnow() + timedelta(minutes=30)).timestamp()) } encoded_jwt = jwt.encode(payload, secret_key, algorithm=algorithm) return encoded_jwt def decode_jwt_token(encoded_jwt, secret_key="your_secret", algorithms=["HS256"]): try: decoded_payload = jwt.decode(encoded_jwt, secret_key, algorithms=algorithms) return decoded_payload except jwt.ExpiredSignatureError as e: return f"Token expired: {e}" except jwt.InvalidTokenError as e: return f"Invalid token: {e}" if __name__ == "__main__": token = create_jwt_token() print(f"Encoded JWT: {token}") decoded_data = decode_jwt_token(token) print(f"Decoded Data: {decoded_data}") ``` ##### Laravel 中的应用 Laravel 框架下集成 Tymon\JWTAuth 扩展包可方便管理基于 JWT 的认证逻辑[^2]。首先需安装依赖库并通过配置文件设置别名以便快速调用相关方法: ```php // 配置 aliases 数组中加入以下内容 'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth', 'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory', // 创建 Token 示例 $user = Auth::user(); $token = JWTAuth::fromUser($user); // 验证 Token 示例 try { $user = JWTAuth::parseToken()->authenticate(); } catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) { // Token过期处理... } ``` #### 5. 安全注意事项 尽管 JWT 提供了一种灵活的身份验证机制,但在实际开发过程中仍需要注意一些潜在的安全隐患。比如避免泄露敏感信息到 Payload 或者 Header 当中;始终保护好 Secret Key 不被暴露给未经授权方等等[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值