跳到主要内容

JWT认证

· 阅读需 5 分钟
Jason Lee

前言

各种认证方式一直是我头痛的点。奇怪的是,几乎所有的 web 开发教程都默认你已经会了,而不会专门教学,只是一笔带过。你只能自己去找博客看。参考视频教程

jwt 归为一种身份验证(authentication)的方式。

令牌(token)

这个词挺神奇的。transformer 结构里有 token 这个概念,这里也有。不过他们的含义应该完全不同。在 web 开发中,token 指的是令牌,或者凭证。

最开始,人们使用 session+cookie 的认证方式。这种情景下,服务器存储用户的相关信息,仅返回给浏览器一个 session-id。浏览器下次请求,将在请求中的 cookie 中携带 session-id,服务器接收到这个 id,并且能查找到相关用户的信息,则认证成功。

但是这种模式越来越不适合当代多服务器的 web 模式。因为这相当于要求每个服务器都要存储一个用户信息表。所以,需要一种新的认证方式。

针对上述问题,一种解决方案是,不在服务器单独建用户信息表,而是将用户信息(token)存起来发给浏览器,浏览器下次来直接带完整的用户信息。然后,因为服务器这时候已经不存储任何用户信息,且所有信息完全来自用户,为了防止用户携带假信息进行欺诈,在发给浏览器的信息中加入签名进行防伪。

至于 JWT 的存储方式,可以是 cookie,也可以是 localstorage 等。

实现方式

上图是 jwt 的结构。三段式,分别是头部、负荷和签名。头部有两个字段:生成签名用到的加密算法和 token 类型。负荷中的 iat 指的是 issue at,签发时间。签名框里的意思是,头部加负荷,再加上密钥,一同经过 sha256 算法,生成了签名。

chatgpt 的解释:

JWT 的验证签名原理如下:

服务端在接收到 JWT 后,会对头部和载荷进行验证,验证包括以下几个步骤:

a. 解析出 JWT 中的头部和载荷,并检查头部中的算法是否为可信的算法。

b. 对头部和载荷使用相同的算法和密钥进行签名,得到签名结果。

c. 将服务端得到的签名结果和 JWT 中附带的签名结果进行比较,如果两个签名结果相同,则认为 JWT 是有效的,否则认为 JWT 是无效的。

通过以上验证过程,JWT 的签名可以保证数据的完整性和真实性,从而确保 JWT 的安全性。值得注意的是,JWT 并不加密,只是通过签名来验证数据的真实性和完整性,因此在使用 JWT 时,应该注意保护 JWT 的传输过程,避免 JWT 被篡改或窃取。

其他

  • 在软件售卖场景中,有把 jwt 作为许可证来使用的。即软件使用过程中不断去读取 jwt token 文件,如果验证出过期,则软件无法使用。与一般的登录场景类似的是,许可证也是由服务端(软件卖方)签发,每次使用都要检查 token。