乐趣区

关于javascript: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};
退出移动版