diff --git a/back/api/auth.ts b/back/api/auth.ts index 8cc5f144..06c86003 100644 --- a/back/api/auth.ts +++ b/back/api/auth.ts @@ -151,13 +151,15 @@ export default (app: Router) => { celebrate({ body: Joi.object({ code: Joi.string().required(), + username: Joi.string().required(), + password: Joi.string().required(), }), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { const authService = Container.get(AuthService); - const data = await authService.twoFactorLogin(req.body); + const data = await authService.twoFactorLogin(req.body, req); res.send(data); } catch (e) { logger.error('🔥 error: %o', e); diff --git a/back/services/auth.ts b/back/services/auth.ts index 98e2368e..0c05394d 100644 --- a/back/services/auth.ts +++ b/back/services/auth.ts @@ -34,6 +34,7 @@ export default class AuthService { lastip, lastaddr, twoFactorActived, + isTwoFactorChecking, } = content; if ( @@ -58,30 +59,35 @@ export default class AuthService { const { ip, address } = await getNetIp(req); if (username === cUsername && password === cPassword) { + if (twoFactorActived && !isTwoFactorChecking) { + this.updateAuthInfo(content, { + isTwoFactorChecking: true, + }); + return { + code: 420, + message: '请输入两步验证token', + }; + } + const data = createRandomString(50, 100); const expiration = twoFactorActived ? 30 : 3; let token = jwt.sign({ data }, config.secret as any, { expiresIn: 60 * 60 * 24 * expiration, algorithm: 'HS384', }); + this.updateAuthInfo(content, { token, lastlogon: timestamp, - retries: twoFactorActived ? retries : 0, + retries: 0, lastip: ip, lastaddr: address, + isTwoFactorChecking: false, }); - if (twoFactorActived) { - return { - code: 420, - message: '请输入两步验证token', - }; - } else { - return { - code: 200, - data: { token, lastip, lastaddr, lastlogon, retries }, - }; - } + return { + code: 200, + data: { token, lastip, lastaddr, lastlogon, retries }, + }; } else { this.updateAuthInfo(content, { retries: retries + 1, @@ -140,22 +146,24 @@ export default class AuthService { return isValid; } - public async twoFactorLogin({ code }) { + public async twoFactorLogin({ username, password, code }, req) { const authInfo = this.getAuthInfo(); - const { token, lastip, lastaddr, lastlogon, retries, twoFactorSecret } = - authInfo; + const { isTwoFactorChecking, retries, twoFactorSecret } = authInfo; + if (!isTwoFactorChecking) { + return { code: 450, message: '未知错误' }; + } const isValid = authenticator.verify({ token: code, secret: twoFactorSecret, }); if (isValid) { - this.updateAuthInfo(authInfo, { retries: 0 }); - return { - code: 200, - data: { token, lastip, lastaddr, lastlogon, retries }, - }; + return this.login({ username, password }, req); } else { - this.updateAuthInfo(authInfo, { retries: retries + 1 }); + const { ip, address } = await getNetIp(req); + this.updateAuthInfo(authInfo, { + lastip: ip, + lastaddr: address, + }); return { code: 430, message: '验证失败' }; } } diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index 3b69d672..418e6df5 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -24,6 +24,7 @@ const Login = () => { const { theme } = useTheme(); const [twoFactor, setTwoFactor] = useState(false); const [verifing, setVerifing] = useState(false); + const [loginInfo, setLoginInfo] = useState(); const handleOk = (values: any) => { setLoading(true); @@ -38,6 +39,10 @@ const Login = () => { }) .then((data) => { if (data.code === 420) { + setLoginInfo({ + username: values.username, + password: values.password, + }); setTwoFactor(true); } else { checkResponse(data); @@ -54,7 +59,7 @@ const Login = () => { setVerifing(true); request .put(`${config.apiPrefix}user/two-factor/login`, { - data: { code: values.code }, + data: { ...loginInfo, code: values.code }, }) .then((data: any) => { if (data.code === 430) {