使用 JWT 实现 RESTful API 接口的无状态认证

什么是 JWT

JWT(JSON Web Token)是一种用于进行跨域认证的开放标准,它定义了一种简洁的、自包含的方式,来在各方之间安全传递信息。

JWT 把用户的信息加密成一个 Token(令牌),通过网络传输到服务器,服务器解密后,利用其中包含的信息进行认证。JWT 是一种无状态认证的方式,它可以避免服务器对每个请求进行存储,从而提高了系统的可伸缩性。

为什么要使用 JWT

在传统的认证方式中,用户登录之后,后端会生成一个 Session ID,并把 Session ID 发送给前端。前端每次请求时,都需要带上 Session ID,后端根据 Session ID 去查找用户状态,从而保持用户的登录状态。

这种方式存在一个问题,就是后端需要对每个 Session ID 进行持久化存储,这在高并发场景下,会导致性能瓶颈。同时,如果后端在多台服务器中进行负载均衡,就需要保证 Session ID 的共享,这就需要增加额外的工作量。

JWT 将用户认证信息加密为一个 Token,前端每次请求时,都会带上 Token,后端只需要解密 Token,就可以获取用户的认证信息,从而实现无状态认证。这种方式可以避免对每个请求进行存储,提高了系统的可伸缩性。

JWT 的组成

JWT 由 Header、Payload 和 Signature 三个部分组成,它们都是字符串,用点号连接起来,通过 Base64 编码,形成一个不可逆转的字符串。

Header

Header 部分是一个 JSON 对象,用来描述 JWT 的元数据。例如:

{
  "alg": "HS256",
  "typ": "JWT"
}

其中,alg 是用来指定加密算法,常用的有 HMAC SHA256(HS256)、RSA SHA256(RS256)和 ECDSA SHA256(ES256)等。

Payload

即负载部分,用来存储用户的认证信息。例如:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

其中,sub 表示用户 ID,name 表示用户名,iat 表示 Token 的创建时间。

Payload 也可以存储其他业务信息,例如用户权限、角色等。

Signature

Signature 部分是对 Header 和 Payload 进行签名,以确保 Token 没有被篡改。签名的方法是用 Header 中的 alg 字段指定的算法进行加密。例如:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

其中,secret 是后端应用程序的一个密钥,它需要保密。

JWT 的使用流程

JWT 的使用流程如下:

  1. 用户通过用户名和密码进行认证。
  2. 后端根据用户信息生成 JWT。
  3. 后端将 JWT 发送给前端,前端存储 JWT。
  4. 前端每次请求时,在请求头中添加 Authorization 字段,值为 Bearer + JWT。
  5. 后端解析 JWT,获得用户的认证信息,并进行认证。

示例代码

生成 JWT

const jwt = require('jsonwebtoken')

const payload = { 
  sub: '1234567890', 
  name: 'John Doe', 
  iat: Math.floor(Date.now() / 1000)
}

const secret = 'mysecretkey'

const token = jwt.sign(payload, secret, { algorithm: 'HS256' })

console.log(token)

解析 JWT

const jwt = require('jsonwebtoken')

const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'

const secret = 'mysecretkey'

jwt.verify(token, secret, function(err, decoded) {
  if (err) {
    console.log(err)
  } else {
    console.log(decoded)
  }
})

总结

JWT 是一种简洁、自包含、可扩展的认证方式,它可以实现无状态认证,避免了在后端对每个请求进行持久化存储的问题。当然,JWT 也不是万能的,它的优缺点需要根据具体业务场景进行选择。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a5b5bfadd4f0e0ffe4532c


纠错反馈