阅读 824

从token中获取用户信息 | 程序员必备小知识

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

在一个项目中,后端告诉我,登录成功后只返回一个token给我,没有额外返回用户信息,用户信息都在token中,自己去取。我看一下token,一堆乱码,这如何获取用户信息?一头雾水,再次询问后端,后端告诉我token是使用JSON Web Token生成,前端应该有解析这类token的JS库,下文将此类token称为JWT TOKEN。

既然后端都这么说了,去研究一下JSON Web Token技术。

JSON Web Token 是什么

JSON web token 可以理解为客户端向服务端发起登录请求后,后端把一些信息用 JSON 来表达,然后把 JSON 用算法加密后生成一个JWT TOKEN发送给客户端,随后客户端每次向服务端请求时,要在请求头中带上JWT TOKEN,服务端在把JWT解密进行认证,认证通过才给客户端返回数据。

咋一看,JWT TOKEN是在服务端用算法加密的,客户端应该不能用算法解密,否则不安全。其实不是这样,缘由先从JWT TOKEN的构成来说起。

JWT TOKEN的结构

image.png

其结构如上图所示分为三个部分:

  • 头部-Header (红色部分)
  • 载荷-Payload(粉红色部分)
  • 签名-Signature (天蓝色部分)

每个部分之间用.分开,就如Header.Payload.Signature,下面依次介绍着几个部分。

头部 Header

Header 部分是使用 Base64URL 算法将一个 JSON 对象转成字符串。

这个 JSON 对象描述 JWT TOKEN 的元数据,通常是下面的样子。

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

其中typ表示TOKEN的类型,alg表示签名-Signature的加密方式,HS256表示用HmacSHA256算法加密。

载荷-Payload

Payload 部分也是使用 Base64URL 算法将一个 JSON 对象转成字符串。

在这个 JSON 对象中用来存放实际需要传递的数据。JWT 规定了7个官方字段。

  • iss :签发人
  • exp :过期时间
  • sub :主题
  • aud :受众
  • nbf :生效时间
  • iat :签发时间
  • jti :编号

这个7个官方字段,无需全部使用,其中exp比较有用,可以和当前时间比较得出该 JWT TOKEN 是否过期。

除了官方字段,还可以定义一些私有字段,但是注意,Payload 部分是不加密的,任何人都可以读到,所以不要把不需要保密的信息放在这个部分。

那么就可以把一些不需要保密的用户信息添加进去,例如:

{
  "id": "1234567890",
  "name": "小明",
  "depId": "1124587"
}
复制代码

签名-Signature

Signature 部分是对前两部分的签名,防止数据篡改,按如下方法进行签名生成一个字符串。

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

其中secret就是HMACSHA256加密算法的密钥,这个密钥只能存放在服务端,当客户端把JWT TOKEN 放在请求头中给服务端发送过来,服务端通过secret密钥进行解密,然后进行认证。

解码载荷-Payload

从上面对JWT TOKEN每个部分的介绍,得知用户信息会存放在JWT TOKEN的第二部分,要对其解码才能获取用户信息。

前面介绍到载荷-Payload的 JSON 对象是用 Base64URL 编码成一个字符串。

这里介绍一个JS库进行解码Payload(载荷),就是jsonwebtoken

执行命令npm install jsonwebtoken --save安装。

使用import jwt from 'jsonwebtoken';引入。

执行以下代码进行解码

const tokenDate = jwt.decode(token);

console.log(tokenDate.name);// 小明
复制代码
文章分类
前端