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是由服务端生成并发放的,其中签名是由服务端的私钥加密而成的,只要保证了私钥的安全,就能保证签名是安全的。