node jwt权限校验

JWT权限校验

每当用户登录的时候,后端将传递给前端一个token,此后前端每次发送请求都会携带token

JWT的常用方法介绍

生成token

jwt.sign(payload, secretOrPrivateKey, [options, callback])

  • payload:json对象或者是可json化的buffer或字符串,这个对象可以存储用户id,会话信息等,这里的信息都是可以使用jwt.verify()方法拿到的.。
  • secretOrPrivateKey:密钥
  • options:参数,JSON对象
    • expiresIn:表示有效期 不带单位默认为秒

比如生成一个token,包含用户的id,设定有效期为1小时

const jwt = require('jsonwebtoken')
let token = jwt.sign({user: '1234'}, 'Fizz', {expiresIn: 60 * 60})
console.log(token)

解析验证token

jwt.verify(token, secretOrPublicKey, [options, callback])

  • token:token字符串 由jwt.sign()方法生成的
  • secretOrPublicKey:密钥,与生成token时的密钥必须相同
  • options:可以设置一些解密的方法
jwt.verify(token, 'Fizz'

创建并发送token过程

温馨提示:不要过多关注代码本身,理解整个业务流程思想

  1. 请求接口,获取输入的账号(或者为email)和密码,传入到emailLogin处理函数中
router.post('/', async (ctx, next) => {
    // 此处为经过校验器后的包含ctx的对象
    const v = await new TokenValidator().validate(ctx)
    let token
    // 此处通过登录方式调用不同的验证方法
    switch (v.get('body.type')) {
        case LoginType.USER_EMAIL:
            token =  await emailLogin(v.get('body.account'), v.get('body.secret'))
            break;
        case LoginType.USER_MINI_PROGRAM:
            break;
        case LoginType.USER_MOBILE:
            break;
        default:
            throw new ParameterException('没有对应的处理函数')
    }
    ctx.body = new Success('获取token成功', token)

})
  1. emailLogin处理函数

verifyEmailPassword函数主要是对传入的accountsecret在数据库中进行比对,

如果数据有所对应的数据,那么就调用generateToken创建token并返回

async function emailLogin(account, secret) {
    const user = await User.verifyEmailPassword(account, secret)
    // 第二个参数代表用户的权限级别
    return  generateToken(user.id, Auth.USER)
}
  1. generateToken创建token
const jwt = require('jsonwebtoken')

const generateToken = function(uid, scope){
    // 获取密钥
    const secretKey = global.config.security.secretKey
    // 获取设定时长
    const expiresIn = global.config.security.expiresIn
    const token = jwt.sign({
        uid,
        scope
    },secretKey,{
        expiresIn
    })
    return token
}

解析token过程

  1. 编写权限处理的中间件
const basicAuth = require('basic-auth')
const jwt = require('jsonwebtoken')
const {Forbidden} = require('../core/http-exception')

class Auth {
    constructor(level) {
        this.level = level || 1
        // 普通用户
        Auth.USER = 8
        // 管理员
        Auth.ADMIN = 16
    }

    get m() {
        return async (ctx,next) => {
            const userToken = basicAuth(ctx.request)
            let errorMessage = 'token不合法'
            // token不存在的情况下
            if (!userToken || !userToken.name) {
                throw new Forbidden(errorMessage)
            }

            // token令牌校验
            try {
                var decode = jwt.verify(userToken.name, global.config.security.secretKey)
            } catch (error) {
                if (error.name === 'TokenExpiredError') {
                    errorMessage = 'token令牌过期'
                }
                throw new Forbidden(errorMessage)
            }
            // 将token中的参数放入ctx中
            ctx.auth = {
                uid:decode.uid,
                scope:decode.scope
            }

            // 用户的权限 < 请求接口的权限
            if (decode.scope < this.level) {
                errorMessage = '权限不足'
                throw new Forbidden(errorMessage)
            }

            await next()
        }
    }
}

module.exports = Auth

重要部分的拆分

获取token

在获取token的时候,我们需要借助basic-auth的插件,用于获取 http headerauthorization 内的值

const userToken = basicAuth(ctx.request)

解析token

此处注意:我们通过basic-auth插件获取到的token是一个对象,我们真正需要的token位于name

 var decode = jwt.verify(userToken.name, global.config.security.secretKey)

权限的比较

// 用户的权限 < 请求接口的权限
if (decode.scope < this.level) {
    errorMessage = '权限不足'
    throw new Forbidden(errorMessage)
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值