持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 3 天,点击查看活动详情
大家好,我是melo,一名大三后台练习生,不知不觉练习时间长达一年了!!!
👉本篇速览
- 前后端分离会话问题以及解决方案
- JWT概述入门
- JWT优势
- JWT残留的问题
- redis白名单&黑名单机制
- HTTPS中的数字签名机制
1、前后端分离会话问题
【1】问题追踪
- 前面我们实现分布式的session会话缓存,但是我们发现此功能的实现是基于浏览的cookie机制,也就是说用户禁用cookie后,我们的系统会就会产生会话不同的问题
- 而且服务端还需要存储session,占据了很多内存空间
【2】解决方案
我们的前端可能是web、Android、ios等应用,同时我们每一个接口都提供了无状态的应答方式,这里我们提供了基于JWT的token生成方案
-
用户登陆之后 , 使用JWT根据用户的特有信息【比如userId】颁发签名并设置过期时间(类似session过期时间相同),返回token给前端
-
前端将token保存到客户端本地,并且之后每次发送请求时都在header上携带token
-
后台设置拦截器,每次请求都验证token是否有效
那么jwt到底是什么呢?
🎈2、JWT概述
JWT(JSON WEB TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式)。它是在Web环境下两个实体之间传输数据的一项标准。实际上传输的就是一个字符串。
- 广义上:JWT是一个标准的名称;
- 狭义上:JWT指的就是用来传递的那个token字符串
JWT由三部分构成:header(头部)、payload(载荷)和signature(签名)。
Header
存储两个变量
- alg:签名算法(也就是下面将Header和payload加密成Signature)默认是 HMAC SHA256(写成 HS256)
- typ:令牌类型,也就是JWT
{
"alg": "HS256",
"typ": "JWT"
}
JSON 形式的 Header 被转换成 Base64 编码,成为 JWT 的第一部分。
payload
存储很多东西,基础信息有如下几个
- 签发人,也就是这个“令牌”归属于哪个用户。一般是
userId - 创建时间,也就是这个令牌是什么时候创建的
- 失效时间,也就是这个令牌什么时候失效(session的失效时间)
- 唯一标识,一般可以使用算法生成一个唯一标识(jti==>sessionId)
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
Payload 部分默认是不加密的,一定不要将隐私信息存放在 Payload 当中!!! JSON 形式的 Payload 被转换成 Base64 编码,成为 JWT 的第二部分。
JWT 的 Token 相当是明文,是可以解密的,任何存在 payload 的东西,都没有秘密可言,所以隐私数据不能签发 token。
Signature
这个是上面两个【Header和payload】经过Header中的算法加密生成的,用于比对信息,防止篡改Header和payload
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。
然后将这三个部分的信息经过加密生成一个JwtToken的字符串,发送给客户端,客户端保存在本地。当客户端发起请求的时候携带这个到服务端(可以是在cookie,可以是在header),在服务端进行验证,我们需要解密对应的payload的内容
优势
- 适合于分布式,因为不需要保存在服务端了
- 而且token自带了payload可以存放一些用来校验的用户信息,相当于客户端存放了,原本用session的话是我们服务端去存一下loginUser在session中,然后他们做敏感操作比如修改的时候,我们通常需要去验证是不是本人,通过他传的userId去跟session中的比较
而现在我们去跟他客户端发过来的token比就好了
残留问题
- 退出登录的时候,一般都是前端删掉保存的token即可,但这样会不会有安全问题呢?这意味着这个token其实还是可以用的,一旦泄露就很危险了,此时我们应该如何处理呢?要知道token一旦签发后,是没办法主动过期的
- token放在header里边,打开控制台就能看到,那别人能否拿到我们的token,去篡改为其他的身份呢?或者说主动捏造一个token
这些问题,我们统一留到下篇来解决~
💠下篇预告
- 本篇简单入门了JWT,并留下了两个安全问题,下篇我们将探探解决方案,涉及到redis白名单&黑名单机制,以及HTTPS中的数字签名机制,敬请期待