写点什么

一起重新全面认识 JWT-Json Web Token

用户头像
谙忆
关注
发布于: 2021 年 02 月 20 日

一起重新全面认识 JWT-Json Web Token

概述

最近学习了一下 JWT,全名为 Json Web Token,是一种自包含令牌。

在这里,我整理了一下网上资源。在文章最后,有一个使用 Java 实现 JWT 生成和验证的完整案例。

简单的说,就是基于 JSON,在 web 环境下传输一个规定格式的字符串令牌。

广义上讲 JWT,这是一个 Web 安全传输信息方式。狭义上来说,直接指传递的令牌字符串。

JWT 官网地址:https://jwt.io/ ,在这里,你可以体验一下形成的 JWT 字符串。



应用场景

首先,我们需要知道,JWT 无法用于数据加密。一般是用来身份提供者和服务者之间传递被认证的用户身份信息,以便于从资源服务器获取到资源。

也可以增加一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。

所以,可以推断出,在以下场景中使用 JWT 是比较合适的。

  • 授权:这是最常见的使用场景,解决单点登录问题。因为 JWT 使用起来轻便,开销小,服务端不用记录用户状态信息(无状态),所以使用比较广泛;

  • 信息交换:JWT 是在各个服务之间安全传输信息的好方法。因为 JWT 可以签名,例如,使用公钥/私钥对儿 - 可以确定请求方是合法的。此外,由于使用标头和有效负载计算签名,还可以验证内容是否未被篡改。

JWT 认证过程

JWT 官网有一张图描述了 JWT 的认证流程



流程说明:

  • 1,浏览器发起请求登陆,携带用户名和密码;

  • 2,服务端验证身份,根据算法,将用户标识符打包生成 token,

  • 3,服务器返回 JWT 信息给浏览器,JWT 不包含敏感信息;

  • 4,浏览器发起请求获取用户资料,把刚刚拿到的 token 一起发送给服务器;

  • 5,服务器发现数据中有 token,验明正身;

  • 6,服务器返回该用户的用户资料;

JWT 的数据结构

JWT 字符串的格式:

header.payload.signature
复制代码

JWT 通常由三部分组成,按照顺序: 头信息(header), 有效载荷(payload)和签名(signature)。

header

header 是一串描述 JWT 元数据的 JSON 字符串,例如:

{"alg":"HS256","typ":"JWT"}
复制代码

HS256 表示使用了 HMAC-SHA256 来生成签名。

最后使用 Base64URL 算法将上述 JSON 对象转换为字符串保存。

其他还有一些签名算法,可以去官网查看。

payload

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了 7 个官方字段,供选用。

 iss (issuer):签发人 exp (expiration time):过期时间(jwt的过期时间,这个过期时间必须要大于签发时间) sub (subject):主题 aud (audience):受众 nbf (Not Before):生效时间(定义在什么时间之前,该jwt都是不可用的.) iat (Issued At):签发时间 jti (JWT ID):编号(jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。)
复制代码

当然,除了前面的字符串,这里也就是我们传输数据的地方。可以自定义字段传输。例如:

 { "微信公众号": "程序编程之旅", "姓名": "谙忆" }
复制代码

当然,我这里就是推广下公众号,前面的 key 用了中文名,你别这么玩就行。

注意哦,这部分的数据默认是不加密的。所以,如果有敏感信息,注意再使用加密算法把数据加密后传输即可。

这个 JSON 对象传输时,也要使用 Base64URL 算法转成字符串。

signature

签名哈希部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。

首先,需要指定一个密码(secret)。该密码保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法(默认情况下为 HMAC SHA256)根据以下公式生成签名。

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
复制代码

token 看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI
复制代码

JWT 的用法

客户端接收服务器返回的 JWT,将其存储在 Cookie 或 localStorage 中。

此后,客户端将在与服务器交互中都会带 JWT。如果将它存储在 Cookie 中,就可以自动发送,但是不会跨域,因此一般是将它放入 HTTP 请求的 Header Authorization 字段中。

当跨域时,也可以将 JWT 放置于 POST 请求的数据主体中。

JWT 的优缺点

1、JWT 默认不加密,所以可能导致数据泄露,但可以加密。生成原始令牌后,可以使用该令牌再次对其进行加密。

2、当 JWT 未加密时,一些私密数据无法通过 JWT 传输。

3、JWT 不仅可用于认证,还可用于信息交换。善用 JWT 有助于减少服务器请求数据库的次数。

4、JWT 的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦 JWT 签发,在有效期内将会一直有效。

5、JWT 本身包含认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。为了减少盗用,JWT 的有效期不宜设置太长。对于某些重要操作,用户在使用时应该每次都进行身份验证。

6、为了减少盗用和窃取,JWT 不建议使用 HTTP 协议来传输代码,而是使用加密的 HTTPS 协议进行传输,防止服务器返回给用户的 JWT 被拦截。

看着上面 6 点,我的建议是,无论有没有敏感数据,对于用户认证信息数据做一层加密。最大程度上避免数据泄露造成问题。

最后,强调一点:JWT 不是用来加密的,只是用来验证用户的真实性以及请求来源的真实性。

最后

希望大家能动动手指,关注公众号:程序编程之旅


关注即可加入技术交流群。更多技术,更多故事,更多精彩内容等您来看。


用户头像

谙忆

关注

CSDN博客专家 2020.02.07 加入

公众号:程序编程之旅。曾经写过C、C++,使用过Cocos2dx开发过游戏、安卓端、IOS端、PC端页面均开发过。目前专注Java开发,SaaS内核、元数据的研究。偶尔玩玩爬虫。 https://chenhx.blog.csdn.net/

评论

发布
暂无评论
一起重新全面认识JWT-Json Web Token