话不多说,直接上代码
登录接口
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};