|
@@ -1,22 +1,67 @@
|
|
|
-import { Config, Inject, InjectClient, Provide } from '@midwayjs/core';
|
|
|
+import { Config, Inject, Provide } from '@midwayjs/core';
|
|
|
import { JwtService } from '@midwayjs/jwt';
|
|
|
import { Context } from '@midwayjs/koa';
|
|
|
import { get } from 'lodash';
|
|
|
-import { LoginError } from '../error/login.error';
|
|
|
+import { FrameworkErrorEnum, LoginError } from '../error/login.error';
|
|
|
+import * as Crypto from 'crypto-js';
|
|
|
+import { RedisService } from '@midwayjs/redis';
|
|
|
|
|
|
@Provide()
|
|
|
export class SingleSignOnService {
|
|
|
@Inject()
|
|
|
- ctx: Context;
|
|
|
+ private ctx: Context;
|
|
|
+ @Config('loginSign')
|
|
|
+ private loginSign;
|
|
|
+ @Config('jwt.secret')
|
|
|
+ private jwtSecret;
|
|
|
+ @Config('jwt.expiresIn')
|
|
|
+ private jwtExpiresIn;
|
|
|
@Inject()
|
|
|
- jwtService: JwtService;
|
|
|
- async index() {
|
|
|
+ private jwtService: JwtService;
|
|
|
+ @Inject()
|
|
|
+ private redisService: RedisService;
|
|
|
+ /**
|
|
|
+ * 单点登录检查
|
|
|
+ */
|
|
|
+ async index(): Promise<void> {
|
|
|
let user;
|
|
|
const token: any = get(this.ctx.request, 'header.token');
|
|
|
if (token) {
|
|
|
const data = this.jwtService.decodeSync(token);
|
|
|
if (data) user = data;
|
|
|
}
|
|
|
- if (!user) throw new LoginError('TEST');
|
|
|
+ if (!user) throw new LoginError(FrameworkErrorEnum.NOT_LOGIN);
|
|
|
+ const { _id, role, login_code } = user;
|
|
|
+ if (!login_code) throw new LoginError(FrameworkErrorEnum.NOT_LOGIN);
|
|
|
+ // 解密
|
|
|
+ const decodeResult = Crypto.AES.decrypt(login_code, this.jwtSecret);
|
|
|
+ const decode = Crypto.enc.Utf8.stringify(decodeResult).toString();
|
|
|
+ // 取出code
|
|
|
+ const codeArr = decode.split(':');
|
|
|
+ const code = codeArr[codeArr.length - 1];
|
|
|
+ // 拼接redis的key
|
|
|
+ const rediskey = `${this.loginSign}:${role}:${_id}`;
|
|
|
+ // 取出当前记录在案的 code
|
|
|
+ const redisCode = await this.redisService.get(rediskey);
|
|
|
+ if (!redisCode)
|
|
|
+ throw new LoginError(FrameworkErrorEnum.ACCOUNT_HAS_EXPIRED);
|
|
|
+ // 判断是否一致
|
|
|
+ if (code === redisCode) {
|
|
|
+ // 一致,延时
|
|
|
+ await this.redisService.expire(rediskey, this.jwtExpiresIn);
|
|
|
+ } else {
|
|
|
+ throw new LoginError(FrameworkErrorEnum.ACCOUNT_LOGGED_IN_ELESWHERE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 检查路由是否在白名单中
|
|
|
+ */
|
|
|
+ inWhiteList(): boolean {
|
|
|
+ const whiteList = {
|
|
|
+ uri: '/login',
|
|
|
+ desc: '',
|
|
|
+ };
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|