在微信小程序中解jwt.payload

Wed Jan 09 2019

使用JWT作认证

我们部门最近正在开发的一个微信小程序将使用原有的一个项目的RESTful api,该Web Service使用JSONWebToken作认证。JWT的数据中包含一段名为payload的数据使用BASE64进行编码的payload数据,包含了一些可以在客户端中使用的身份信息和token有效期等数据。

Nodejs解JWT的payload

在Nodejs中解JWT的payload最简单,可以直接使用JSONWebToken库中的decode()函数可轻松获得:

JavaScript
|
const jwt = require('jsonwebtoken'); let token = "YOUR_TOKEN"; let payload = jwt.decode(token);

Web前端中解JWT的payload

在Web前端中要解JWT的payload也很简单

JavaScript
|
var base64Url = token.split('.')[1]; var base64 = base64Url.replace('-', '+').replace('_', '/'); var payload = JSON.parse(window.atob(base64));

实现原理是:

  • 将token中通过.分割取中间(下标1)的字符串,并替换相应字符;
  • 使用window.atob()函数将base64进行解码;
  • 最后将解除来的JSON string 转成JSONObject;

经过检查JSONWebToken库的原码,发现也是这个原理,只是解码base64的方式不同。

微信小程序解JWT的payload

根据上面的思路,要实现在微信小程序中解JWT的payload,只需要改用微信小程序中内置的base64库来解即可。

JavaScript
|
let payloadEncoded = token.split('.')[1]; let buffer = wx.base64ToArrayBuffer(payloadEncoded); let payloadDecoded = String.fromCharCode.apply(null, new Uint8Array(buffer)); let payload = JSON.parse(payloadDecoded);

微信小程序JWT payload工具

为了在微信小程序端方便的解码和验证JWT,我编写了一个这样的类:

JavaScript
|
/** * @author ShinChven Zhang * 在微信小程序中解jwt中的payload,并进行有效验证。 */ class JWTPayload { /** * encoded JSONWebToken */ constructor(token) { this.payload = this.decodePayload(token); } /** * 解token * token JSONWebToken * return payload object */ decodePayload(token) { try { let payloadEncoded = token.split('.')[1]; let buffer = wx.base64ToArrayBuffer(payloadEncoded); let payloadDecoded = String.fromCharCode.apply(null, new Uint8Array(buffer)); return JSON.parse(payloadDecoded) } catch (err) { console.error(err); return null } } /** * 验证是否有效 * return boolean */ isValid() { try{ if (this.payload && this.payload.exp) { let timestamp = Date.parse(new Date()); timestamp = timestamp / 1000; console.log(timestamp) return this.payload.exp > timestamp; } }catch(err){ console.error(err); } return false; } } module.exports = JWTPayload

使用:

JavaScript
|
let jwt = new JWTPayload(token); if (jwt.isValid()){ console.log(jwt.payload); }