【权限】大家好,请教一个接口权限控制的问题
发布于 2 年前 作者 BengBu-YueZhang 1562 次浏览 来自 问答

下面这端代码是我为我的小项目设计的权限控制的中间件,首先验证token是否合法,然后从token中提取出角色的信息,读取redis中该角色的权限,判断该角色是否拥有接口所需要的权限。


const jwt = require('jsonwebtoken')
const secret = require('../config/jwt').secret
const redisClient = require('../config/redis')
const { promisify } = require('util')
const getAsync = promisify(redisClient.get).bind(redisClient)
const acl = require('./../config/acl').acl

/**
 * 登录权限控制
 * @param {String} model 权限的模块
 * @param {String} auth 权限名称
 */
module.exports = function (model, auth) {
  return async function (ctx, next) {
    const token = ctx.headers['x-access-token']
    if (token) {
      jwt.verify(token, secret, function (err, decoded) {
        if (err) {
          ctx.throw(403, 'token已过期')
        } else {
          // 使用redis进行登录的验证, 避免没有登录的时候, 使用之前的token进行访问
          // 从token中获取id信息以及角色信息
          const { id, role } = decoded
          getAsync(id).then(res => {
            if (!res) return ctx.throw(403, 'token失效')
            ctx.decoded = decoded
            if (!model || !auth) {
              next()
            } else {
              // 接口权限验证
              acl.areAnyRolesAllowed(role, model, auth, function (err, result) {
                if (result) {
                  next()
                } else {
                  return ctx.throw(403, '没有操作权限')
                }
              })
            }
          }).catch(err => {
            return ctx.throw(403, 'token失效')
          })
        }
      })
    } else {
      ctx.throw(403, '缺少token信息')
    }
  }
}

下面是我auth的schema的设计

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const AuthSchema = new Schema({
  // 权限的代码
  code: {
    type: String,
    unique: true,
    required: true
  },
  // 权限的名称
  name: {
    type: String,
    required: true
  }
})

module.exports = AuthSchema

一个疑问,在做权限判断的时候,我应该使用auth的code还是auth的ObjectId做判断???????

2 回复

我觉得问题应该是指应该用哪个字段与角色关联,以及权限与资源如何绑定(推测是用code)。

  • 角色使用code与权限项关联

相当于是在角色上冗余code字段,优点就是减少查询次数,缺点是权限项的维护复杂一些

  • 角色使用ObjectId与权限项关联

查询的时候多查一下权限表,再判读角色是否有指定code的权限

各有优点,个人认为后者更合理。

建议token里不要放角色,token只是个用户id,然后把用户id与角色的映射放在权限中间件中。这样解耦合,方便修改角色。你的需求都可以用Casbin来做:https://github.com/casbin/node-casbin

回到顶部