nodejs 后端 token 权限问题

//登录接口

export default class AuthController {
  static async login(req, res) {
    try {
      const { name, password } = req.body;

      if (!name || typeof name !== "string") {
        res.status(400).json(resultFail("Bad name format, expected string."));
        return;
      }
      if (!password || typeof password !== "string") {
        res.status(400).json(resultFail("Bad password format, expected string."));
        return;
      }

      let userFromDB = await AuthDAO.getUser(name);
      if (!userFromDB) {
        res.status(401).json(resultFail("Make sure your name is correct."));
        return;
      }

      const user = new AuthUser(userFromDB);
      if (!(await user.comparePassword(password))) {
        res.status(401).json(resultFail("Make sure your password is correct."));
        return;
      }
      user.encoded().then((token) => {
        let option = {
          token: token,
          userName: userFromDB.name,
          role: userFromDB.privilege
        }
        userManager.setCurrentCacheToken(option);
        res.send(resultSuccess({
          auth_token: token,
          ...user.toJson()
        }))
      });
    } catch (e) {
      res.status(400).json(resultFail(e));
    }
  }

}

//权限分配对应接口

import { token } from 'morgan';
import {
    ADMIN,
    NORMAL,
    ANONYMOUS
} from './common/constants';
import { resultFail } from './common/utils';
import path from "path";

// API for different permission
const api4anonymous = [
    "/api/devices/",
    "/api/devices/get-device",
    "/sys/health-check",
    "/sys/access-log",
    "/auth/login"
]

const api4normal = [
    "/api/devices/",
    "/api/devices/get-device",
    "/sys/health-check",
    "/sys/access-log",
    "/auth/login"
]

const api4admin = [
    "all"
]

const rolePermission = new Map([
    [ADMIN, api4admin],
    [NORMAL, api4normal],
    [ANONYMOUS, api4normal],
]);

class UserManager{
    #cacheToken;
    #apiPermissionMap;

    constructor(){
        this.#cacheToken = {
            token : '',
            role : ANONYMOUS,
            userName : ''
        };
        this.#apiPermissionMap = rolePermission;
    }

    setCurrentCacheToken(option){
        // token empty indicate role is anonymous 
        if (option.token !== ''){
            if (typeof(option.token) == 'string'){
                this.#cacheToken.token = option.token;
            }

            if (typeof(option.role) == 'number'){
                this.#cacheToken.role = option.role;
            }

            if (typeof(option.userName) == 'string'){
                this.#cacheToken.userName = option.userName;
            }

        }
    }

    getCurrentCacheToken(){
        return this.#cacheToken;    
    }
    
    verifyApiPermission(reqUrl){
        let role = this.#cacheToken['role'];

        if (this.#cacheToken.token === ''){
            role = ANONYMOUS;
        }

        if (this.#apiPermissionMap.has(role)){
            // admin can do anything
            if(role === ADMIN){
                return true;
            }

            if(this.#apiPermissionMap.get(role).indexOf(reqUrl) !== -1){
                return true;
            }
        }
        return false;
    }
};

function reqPermissionHandler(req, res, next){
    const reqUrl = path.join(req.baseUrl, req.url);
    let token = req.get("authorization");
    if (!token){
        token = '';
    }
    else{
        token = token.slice("Bearer ".length);
    }

    if (token != userManager.getCurrentCacheToken().token && token !== ''){
        res.status(401).json(resultFail(('token error')));
        return;
    }

    if (userManager.verifyApiPermission(reqUrl)){
        next();
    }
    else{
        res.status(403).json(resultFail(('No Permission')));
        return;
    }
}

let userManager = new UserManager();
function userName(){
    return userManager.getCurrentCacheToken().userName;
} 
export {reqPermissionHandler, userManager, userName};

你可能感兴趣的:(nodejs 后端 token 权限问题)