使用JWT对Koa2进行token认证

3 篇文章 0 订阅

JWT

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
流程图:
在这里插入图片描述

例子

工具代码(下面代码会用到)

class Utils {
    CallbackModel(ctx, status, message, data) {
        ctx.response.status = status;
        ctx.body = {
            code: status,
            message: message,
            data: data,
        };
    }
}

module.exports = new Utils;

1. 创建token

  • 登录接口
const { secret } = require('../config'); //   secret 就是一个变量,自己定义名称即可
const jwt = require('jsonwebtoken');

  // 登录
  async login(ctx) {
        ctx.verifyParams({
            name: { type: 'string', required: true },
            password: { type: 'string', required: true },
        });
        try {
            const user = await User.findOne(ctx.request.body);
            if (!user) {
                CallbackModel(ctx, 404, '请输入正确账号密码', {})
                return;
            }
            // jwt 签发
            const { _id, name } = user;
            const token = jwt.sign({ _id, name }, secret, { expiresIn: '1d' });
            CallbackModel(ctx, 200, '登录成功', { token, name })
        } catch (err) {
            CallbackModel(ctx, 500, '错误', JSON.stringify(err))
        }
    }

在这里插入图片描述

2. 验证token

在这里插入图片描述
这个 auth 是 koa-jwt 已经写好的中间件,但是下图展示返回结果不是很友好,so,我们得手动写一个auth中间件的方法

  • postman调试结果
    在这里插入图片描述

3. 编写auth.js 的中间件,中间件的返回的结果需要是function类型

  • 创建 middleware/auth.js
  • 编写代码
const jwt = require('jsonwebtoken');
const util = require('util');
const { CallbackModel } = require('../utils')

const { secret } = require('../config');
const verify = util.promisify(jwt.verify);

module.exports = function() {
    return async function(ctx, next) {
        try {
            const { authorization = '' } = ctx.request.header;
            const token = authorization.split(' ')[1];
            if (!token) {
                CallbackModel(ctx, 404, '缺失Token信息', {})
                return;
            }
            try {
                // 解密payload,获取用户名和ID
                const payload = await verify(token, secret);
                ctx.state = {
                    name: payload.name,
                    _id: payload._id,
                };
                await next(); //运行完毕,交给下一个中间件
            } catch (err) {
               if (JSON.stringify(err).search(/JsonWebTokenError/)) {
                    CallbackModel(ctx, 401, 'Token无效', JSON.stringify(err))
                } else {
                    CallbackModel(ctx, 500, '未知错误', JSON.stringify(err))
                }
            }
        } catch (err) {
            CallbackModel(ctx, 500, '错误', JSON.stringify(err))
        }
    }
}
  • 使用auth的中间件(routes/users.js)
    在这里插入图片描述
  • postman调试结果
    在这里插入图片描述
    这个auth中间是那个路由需要校验,就引入该方法,比如下的方法简单多了
		// app.js
		const koa = require('koa');
		
		app.use(koajwt({
		    secret: 'my_token'
		}).unless({
		    path: [/\/user\/login/]
		}));

总结:

安全性

  1. 如果 JWT 的加密密钥泄露的话,那么就可以通过密钥生成 token,随意的请求 API 了。因此密钥绝对不能存在前端代码中,不然很容易就能被找到。
  2. 在 HTTP 请求中,token 放在 header 中,中间者很容易可以通过抓包工具抓取到 header 里的数据。而 HTTPS 即使能被抓包,但是它是加密传输的,所以也拿不到 token,就会相对安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值