一、安装包文件
npm install jsonwebtoken --save
二、通过jsonwebtoken可以创建token
const jwt = require('jsonwebtoken') // 创建token let token = jwt.sign(obj,secret,opt) //解码token let payload = jwt.verify(token,secret)
实现思路
login处理
当我们收到前台传来的帐号密码查库比对通过后,创建token并返回客户端
const police = require("../../../model/police"); const jwt = require('jsonwebtoken') let myPolice = new police(); let {secret} = require('../../../util/secret.js') async function login(ctx, next) { let postData = ctx.request.body let selectResult = await myPolice.checkLogin(postData) if (selectResult.err) { ctx.body = { status: 1, message: err } } else if (!selectResult.result) { ctx.body = { status: 1, message: '用户不存在' } } else if (selectResult.result[0].password !== postData.password) { ctx.body = { status: 1, message: '密码错误' } } else { // 帐号密码正确 创建token //payload中写入一些值 time:创建日期 timeout:多长时间后过期 let payload = {userNumber:postData.userNumber,time:new Date().getTime(),timeout:1000*60*60*2} let token = jwt.sign(payload, secret); ctx.body = { status: 0, message: '登录成功', data:{ token } } } } module.exports = login
Payload参数说明
iss: 签发者 sub: 面向用户 aud: 接收者 iat(issued at): 签发时间 exp(expires): 过期时间 nbf(not before):不能被接收处理时间,在此之前不能被接收处理 jti:JWT ID为web token提供唯一标识 例如 {"sub":"subject","aud":"sina.com","iss":"baidu.com","iat":1528360628,"nbf":1528360631,"jti":"253e6s5e","exp":1528360637}
jwt.sign(object,key)说明
两个参数分别是签名算法和自定义的签名Key(盐)。签名key可以byte[] 、String及Key的形式传入。前两种形式均存入builder的keyBytes属性,后一种形式存入builder的key属性。如果是第二种(及String类型)的key,则将其进行base64解码获得byte[] 。
三、如何进行token校验
1、创建checkToken.js
文件的中间件
1、token解密方法一
const jwt = require('jsonwebtoken') async function check(ctx, next) { let url = ctx.url.split('?')[0] // 如果是登陆页面和注册页面就不需要验证token了 if (url === '/admin/user/login' || url === '/admin/user/register') { await next() } else { // 否则获取到token let token = ctx.request.headers["authorization"] if (token) { // 如果有token的话就开始解析 const tokenItem = jwt.verify(token, 'token') // 将token的创建的时间和过期时间结构出来 const { time, timeout } = tokenItem // 拿到当前的时间 let data = new Date().getTime(); // 判断一下如果当前时间减去token创建时间小于或者等于token过期时间,说明还没有过期,否则过期 if (data - time <= timeout) { // token没有过期 await next() } else { ctx.body = { status: 405, message:'token 已过期,请重新登陆' } } } } } module.exports = checkToken
2、token解密方法二
const Promise = require("bluebird"); const jwt = require("jsonwebtoken"); const verify = Promise.promisify(jwt.verify); let { secret } = require("../util/secret"); async function check(ctx, next) { let url = ctx.request.url; // 登录 不用检查 if (url == "/users/login") await next(); else { // 规定token写在header 的 'autohrization' let token = ctx.request.headers["authorization"]; // 解码 let payload = await verify(token,secret); let { time, timeout } = payload; let data = new Date().getTime(); if (data - time <= timeout) { // 未过期 await next(); } else { //过期 ctx.body = { status: 50014, message:'token 已过期' }; } } } module.exports = check
四、在app.js入口中注册使用
const checkToken = require('./middleware/checkToken.js') // 验证token的中间件函数 app.use(checkToken)