Files
certd/packages/ui/certd-server/src/middleware/authority.ts
T

137 lines
3.9 KiB
TypeScript
Raw Normal View History

2024-08-27 13:46:19 +08:00
import { Init, Inject, MidwayWebRouterService, Provide, Scope, ScopeEnum } from '@midwayjs/core';
2023-06-27 09:29:43 +08:00
import { IMidwayKoaContext, IWebMiddleware, NextFunction } from '@midwayjs/koa';
2024-07-15 00:30:33 +08:00
import jwt from 'jsonwebtoken';
import { Constants, SysPrivateSettings, SysSettingsService } from '@certd/lib-server';
2024-11-04 16:39:02 +08:00
import { logger } from '@certd/basic';
import { AuthService } from '../modules/sys/authority/service/auth-service.js';
import { OpenKeyService } from '../modules/open/service/open-key-service.js';
2025-01-19 00:33:34 +08:00
import { RoleService } from '../modules/sys/authority/service/role-service.js';
/**
* 权限校验
*/
@Provide()
2024-08-27 13:46:19 +08:00
@Scope(ScopeEnum.Singleton)
export class AuthorityMiddleware implements IWebMiddleware {
2023-06-27 09:29:43 +08:00
@Inject()
webRouterService: MidwayWebRouterService;
@Inject()
authService: AuthService;
2024-08-27 13:46:19 +08:00
@Inject()
2025-01-19 00:33:34 +08:00
roleService: RoleService;
@Inject()
openKeyService: OpenKeyService;
@Inject()
2024-08-27 13:46:19 +08:00
sysSettingsService: SysSettingsService;
secret: string;
@Init()
async init() {
const setting: SysPrivateSettings = await this.sysSettingsService.getSetting(SysPrivateSettings);
this.secret = setting.jwtKey;
}
resolve() {
return async (ctx: IMidwayKoaContext, next: NextFunction) => {
2023-06-27 09:29:43 +08:00
// 查询当前路由是否在路由表中注册
2024-07-15 00:30:33 +08:00
const routeInfo = await this.webRouterService.getMatchedRouterInfo(ctx.path, ctx.method);
2023-06-27 22:45:27 +08:00
if (routeInfo == null) {
// 404
await next();
return;
}
2023-06-27 09:29:43 +08:00
const permission = routeInfo.summary;
if (permission == null || permission === '') {
ctx.status = 500;
2024-07-15 00:30:33 +08:00
ctx.body = Constants.res.serverError('该路由未配置权限控制:' + ctx.path);
2023-06-27 09:29:43 +08:00
return;
}
2023-06-27 09:29:43 +08:00
if (permission === Constants.per.guest) {
await next();
return;
}
2023-06-27 09:29:43 +08:00
let token = ctx.get('Authorization') || '';
token = token.replace('Bearer ', '').trim();
2024-10-05 01:46:25 +08:00
if (!token) {
2023-06-27 22:45:27 +08:00
//尝试从cookie中获取token
const cookie = ctx.headers.cookie;
if (cookie) {
const items = cookie.split(';');
for (const item of items) {
if (!item || !item.trim()) {
continue;
}
const [key, value] = item.split('=');
if (key.trim() === 'certd_token') {
token = value.trim();
break;
}
}
}
2023-06-27 22:45:27 +08:00
}
2024-10-05 01:46:25 +08:00
if (!token) {
2023-06-27 22:45:27 +08:00
//尝试从query中获取token
token = (ctx.query.token as string) || '';
}
2023-06-27 09:29:43 +08:00
2025-01-19 00:33:34 +08:00
if (token) {
try {
ctx.user = jwt.verify(token, this.secret);
} catch (err) {
logger.error('token verify error: ', err);
return this.notAuth(ctx);
}
} else {
//找找openKey
const openKey = await this.doOpenHandler(ctx);
if (!openKey) {
return this.notAuth(ctx);
}
if (permission === Constants.per.open) {
await next();
2023-06-27 09:29:43 +08:00
return;
2025-01-19 00:33:34 +08:00
} else if (openKey.scope === 'open') {
return this.notAuth(ctx);
2023-06-27 09:29:43 +08:00
}
}
2025-01-19 00:33:34 +08:00
if (permission === Constants.per.authOnly) {
await next();
return;
}
const pass = await this.authService.checkPermission(ctx, permission);
if (!pass) {
logger.info('not permission: ', ctx.req.url);
2025-03-09 16:22:22 +08:00
ctx.status = 200;
2025-01-19 00:33:34 +08:00
ctx.body = Constants.res.permission;
return;
}
2025-01-19 01:07:20 +08:00
await next();
};
}
2025-01-19 00:33:34 +08:00
private notAuth(ctx: IMidwayKoaContext) {
ctx.status = 401;
ctx.body = Constants.res.auth;
return;
}
async doOpenHandler(ctx: IMidwayKoaContext) {
//开放接口
2025-01-19 00:33:34 +08:00
const openKey = ctx.get('x-certd-token') || '';
if (!openKey) {
2025-01-19 00:33:34 +08:00
return null;
}
//校验 openKey
const openKeyRes = await this.openKeyService.verifyOpenKey(openKey);
2025-01-19 00:33:34 +08:00
const roles = await this.roleService.getRoleIdsByUserId(openKeyRes.userId);
ctx.user = { id: openKeyRes.userId, roles };
ctx.openKey = openKeyRes;
2025-01-19 00:33:34 +08:00
return openKeyRes;
}
}