Advertisement

什么是 JWT(Json Web Token)

阅读量:

文章目录

      • 一、身份认证
        • 1.基于 session 的认证机制
      • session 认证的弊端
    • 2.基于 token 的鉴权机制

      • token 的优点

      • 二、JWT 结构

        • 1.头部(header)
    • 2.载荷(payload)

      • ① 标准注册声明
      • ② 公共声明
      • ③ 私有声明
    • 3.签名(signature)

      • 三、客户端处理 JWT
      • 四、JWT 的几个特点

一、身份认证

常见的服务器端身份认证机制有两种,分别为:

1.基于 session 的认证机制

HTTP 采用无状态设计,在缺省状态下每次请求均需用户输入用户名与密码以完成身份认证流程。 session 机制则主要用于服务器端记录用户的登录信息。

session 是一种由服务器产生的唯一标识符,在线性代数中用于精确识别每个访问者。完成身份验证后, 服务器不仅生成一组独特的标识符,还会将其存储于服务端, 同时将其包含在返回的数据包(即Cookie字段)中。客户端接收这一数据包后, 将其作为cookie记录下来。当同一设备或用户在同一时间段内再次访问该服务时, 浏览器会自动发送cookie信息给服务端, 以便核实其身份信息; 当服务端接收到cookie请求时, 就会核实其与之前存储的一致性, 进而确认用户的合法性; 这种基于session的技术成功替代了传统的用户名密码认证流程.

session 认证的弊端

增加开销:因为 session 都被存储在 server 内存中,在认证用户数量增多的情况下, server 的负载压力将显著增大。

缺乏良好的扩展性:用户认证信息以数据库或内存的形式存储,在分布式系统架构下会增加系统的扩展难度

由于利用了Cookies来进行身份验证的过程而CSRF攻击变得较为常见

2.基于 token 的鉴权机制

该鉴权机制基于 Token 原理运作,在服务端并不需要存储用户的认证信息或会话数据。这意味着该应用无需关心用户登录于哪台服务器这一问题即可实现功能拓展:

作为规范性标准使用的缩略语JWT(全称Json Web Token),其主要作用是实现可靠的数据传输。当系统识别用户的身份信息时,在首次授权验证完成后, 服务端会生成带有数字签名的JSON对象并发送给客户端设备进行处理。客户端接收到该JSON对象后保存于本地以便后续处理所有请求中的身份验证需求

token 的优点

在服务器端维护secret密钥的同时,并不需要存储任何会话信息。每个用户的身份是基于token实时计算得出的。通过将空间资源转换为计算能力来减少延迟

二、JWT 结构

JWT 是由三段字符串与两个.组成,这三段字符串按顺序依次为:

1.头部(header)

元数据部分位于顶端。它作为一个 JSON 对象存在,并且包括使用签名的算法以及类型的 getToken 信息。例如

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

上述头部alg属性指定签名算法为 HS256 算法, 即代表 JWT 的默认加密算法; 而 typ 表示令牌类型也就是 JWT 本身.

2.载荷(payload)

在 JWT 格式中(或说是 JSON 格式中),"load"(或称"load")这一字段同样是一个对象类型的数据结构,在此字段中存储与声明相关的数据信息。该字段由三个组成部分构成:分别是...

① 标准注册声明

预定义的声明,即标准规定的字段,并不强制使用,但一般推荐使用。它们有:

iss:JWT 的签发者/发行人

sub:该 JWT 面向的用户

aud:接收方

exp:JWT 的过期时间,必须大于签发时间

nbf:JWT 的生效时间,在这个时间之前该 token 都是无效的

iat:JWT 的签发时间

jti:JWT 唯一身份标识,主要用来作为一次性 toekn,从而避免重放攻击

② 公共声明

公共声明能够包含任意类型的信息,并且通常会包含用户的个人信息以及其他相关业务数据。为了确保安全性考虑,请避免加入敏感性较高的内容。由于这部分内容在客户端端是可以解密的

③ 私有声明

私有声明是服务器端与客户端联合制定的协议说明书,在此建议不要在此处加入敏感数据细节。这是因为使用base64编码时采用的是symmetrical decryption方式,在这种情况下所处理的信息类型应被归类为plaintext information。

下面是一个有效荷载的例子:

复制代码
    {
    	"iss": "www.wjiaman.fun",
    	"sub": "1234567890",
    	"name": "John Doe",
    	"admin": true
    }

对其进行加密,即可得到 JWT 的第 2 部分。

3.签名(signature)

JWT 的第3部分是一个签证信息,该签证信息由 3 个部分组成:

header(base64加密后)

payload(base64加密后)

secret

首先必须先确定一个密钥secret仅限于服务器拥有用于生成和验证jwt这些操作而服务端的私钥则属于敏感信息不可泄露一旦知道了这个secret就可以独立完成对token的生成任务

随后, 采用 header 中指定的签名机制进行加盐加密 header.payload 生成签证(其中 header 和 payload 均为加密后的字符串)

复制代码
    // javascript
    let encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
    let signature = HMACSHA256(encodedString, 'secret');

完成签名计算后,在生成响应时通过使用.符号将 Header、Payload 和 Signature 连接起来即可发送给客户端

三、客户端处理 JWT

当客户端接收到服务器返回的 token 时,可以选择性地将其保存于 Cookie 对象中;或者保留在浏览器本地存储 localStorage 中。

之后,在每次客户端向服务器发起通信请求时都需要携带这个 token。如果将其放入 cookie 中,则浏览器会自动发送给服务器端处理。然而这一做法存在局限性:其缺点在于无法跨越域边界。因此一个更好的解决方案是在 HTTP 请求头信息中的某个特定字段(例如 Authorization)中存储该 token。

另一种做法是,跨域请求时,token 就放在 POST 请求所提交的数据里。

四、JWT 的几个特点

基于 payload 部分的存在, JWT 具备能力承载一部分非敏感性的业务逻辑信息

JWT 未采用加密技术。应避免将任何敏感信息存储于 payload字段中。(其中 payload字段是唯一允许存储自定义数据的部分.) 客户端系统可通过解析解析 payload中的所有内容来获取所需信息.

JWT 的关键标识部分是 signature。该系统通过 signature 来验证 payload 中的信息是否准确无误,并以此防止 payload 内容被篡改。

JWT未被加密,默认情况下是解密状态;然而,在生成原始token后还可以进一步加密以提高安全性。具体而言,在生成原始token之后可以通过密钥对token进行二次加密以增强安全性

JWT 在不加密的情况下,不能将敏感数据写入 JWT。

JWT 不仅可以用于认证而且还可以用于信息交换。合理利用 JWT 可以减少服务器查询数据库的次数

最显著的问题之一在于:尽管服务器本身并未存储任何与状态相关的元数据(metadata),因此系统无法在使用期间主动删除某个 token(token),使其失效或修改其权限范围,并可同时调整相应 token 的权限范围。换句话说,在未部署额外逻辑的情况下(unless additional logic is deployed on the server side),生成后的 JWT 在未达到指定时间前始终有效。

每个 JWT 都附带认证信息, 如果被泄露, 所有用户都将继承对应令牌的所有权限. 为了降低令牌被盗的可能性, 建议 JWT 的有效期限不宜过长. 同时, 避免通过非加密的 HTTP 协议传输数据, 建议采用 HTTPS 协议进行数据传输.

全部评论 (0)

还没有任何评论哟~