登录支持人机验证

This commit is contained in:
CaIon 2023-11-06 22:11:05 +08:00
parent af8827d269
commit a0b975fc3d
5 changed files with 36 additions and 9 deletions

View File

@ -27,9 +27,6 @@ func GetStatus(c *gin.Context) {
"wechat_qrcode": common.WeChatAccountQRCodeImageURL, "wechat_qrcode": common.WeChatAccountQRCodeImageURL,
"wechat_login": common.WeChatAuthEnabled, "wechat_login": common.WeChatAuthEnabled,
"server_address": common.ServerAddress, "server_address": common.ServerAddress,
"pay_address": common.PayAddress,
"epay_id": common.EpayId,
"epay_key": common.EpayKey,
"price": common.Price, "price": common.Price,
"turnstile_check": common.TurnstileCheckEnabled, "turnstile_check": common.TurnstileCheckEnabled,
"turnstile_site_key": common.TurnstileSiteKey, "turnstile_site_key": common.TurnstileSiteKey,

View File

@ -30,7 +30,7 @@ func SetApiRouter(router *gin.Engine) {
userRoute := apiRouter.Group("/user") userRoute := apiRouter.Group("/user")
{ {
userRoute.POST("/register", middleware.CriticalRateLimit(), middleware.TurnstileCheck(), controller.Register) userRoute.POST("/register", middleware.CriticalRateLimit(), middleware.TurnstileCheck(), controller.Register)
userRoute.POST("/login", middleware.CriticalRateLimit(), controller.Login) userRoute.POST("/login", middleware.CriticalRateLimit(), middleware.TurnstileCheck(), controller.Login)
//userRoute.POST("/tokenlog", middleware.CriticalRateLimit(), controller.TokenLog) //userRoute.POST("/tokenlog", middleware.CriticalRateLimit(), controller.TokenLog)
userRoute.GET("/logout", controller.Logout) userRoute.GET("/logout", controller.Logout)
userRoute.GET("/epay/notify", controller.EpayNotify) userRoute.GET("/epay/notify", controller.EpayNotify)

View File

@ -49,5 +49,5 @@
"singleQuote": true, "singleQuote": true,
"jsxSingleQuote": true "jsxSingleQuote": true
}, },
"proxy": "https://nekoapi.com" "proxy": "http://localhost:3000"
} }

View File

@ -2,8 +2,9 @@ import React, { useContext, useEffect, useState } from 'react';
import { Button, Divider, Form, Grid, Header, Image, Message, Modal, Segment } from 'semantic-ui-react'; import { Button, Divider, Form, Grid, Header, Image, Message, Modal, Segment } from 'semantic-ui-react';
import { Link, useNavigate, useSearchParams } from 'react-router-dom'; import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { UserContext } from '../context/User'; import { UserContext } from '../context/User';
import { API, getLogo, showError, showSuccess, showWarning } from '../helpers'; import {API, getLogo, showError, showInfo, showSuccess, showWarning} from '../helpers';
import { onGitHubOAuthClicked } from './utils'; import { onGitHubOAuthClicked } from './utils';
import Turnstile from "react-turnstile";
const LoginForm = () => { const LoginForm = () => {
const [inputs, setInputs] = useState({ const [inputs, setInputs] = useState({
@ -15,6 +16,9 @@ const LoginForm = () => {
const [submitted, setSubmitted] = useState(false); const [submitted, setSubmitted] = useState(false);
const { username, password } = inputs; const { username, password } = inputs;
const [userState, userDispatch] = useContext(UserContext); const [userState, userDispatch] = useContext(UserContext);
const [turnstileEnabled, setTurnstileEnabled] = useState(false);
const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
const [turnstileToken, setTurnstileToken] = useState('');
let navigate = useNavigate(); let navigate = useNavigate();
const [status, setStatus] = useState({}); const [status, setStatus] = useState({});
const logo = getLogo(); const logo = getLogo();
@ -27,6 +31,10 @@ const LoginForm = () => {
if (status) { if (status) {
status = JSON.parse(status); status = JSON.parse(status);
setStatus(status); setStatus(status);
if (status.turnstile_check) {
setTurnstileEnabled(true);
setTurnstileSiteKey(status.turnstile_site_key);
}
} }
}, []); }, []);
@ -37,6 +45,10 @@ const LoginForm = () => {
}; };
const onSubmitWeChatVerificationCode = async () => { const onSubmitWeChatVerificationCode = async () => {
if (turnstileEnabled && turnstileToken === '') {
showInfo('请稍后几秒重试Turnstile 正在检查用户环境!');
return;
}
const res = await API.get( const res = await API.get(
`/api/oauth/wechat?code=${inputs.wechat_verification_code}` `/api/oauth/wechat?code=${inputs.wechat_verification_code}`
); );
@ -58,9 +70,13 @@ const LoginForm = () => {
} }
async function handleSubmit(e) { async function handleSubmit(e) {
if (turnstileEnabled && turnstileToken === '') {
showInfo('请稍后几秒重试Turnstile 正在检查用户环境!');
return;
}
setSubmitted(true); setSubmitted(true);
if (username && password) { if (username && password) {
const res = await API.post(`/api/user/login`, { const res = await API.post(`/api/user/login?turnstile=${turnstileToken}`, {
username, username,
password password
}); });
@ -109,6 +125,16 @@ const LoginForm = () => {
value={password} value={password}
onChange={handleChange} onChange={handleChange}
/> />
{turnstileEnabled ? (
<Turnstile
sitekey={turnstileSiteKey}
onVerify={(token) => {
setTurnstileToken(token);
}}
/>
) : (
<></>
)}
<Button color='green' fluid size='large' onClick={handleSubmit}> <Button color='green' fluid size='large' onClick={handleSubmit}>
登录 登录
</Button> </Button>

View File

@ -155,8 +155,12 @@ const SystemSetting = () => {
} }
let PayAddress = removeTrailingSlash(inputs.PayAddress); let PayAddress = removeTrailingSlash(inputs.PayAddress);
await updateOption('PayAddress', PayAddress); await updateOption('PayAddress', PayAddress);
if (inputs.EpayId !== '') {
await updateOption('EpayId', inputs.EpayId); await updateOption('EpayId', inputs.EpayId);
}
if (inputs.EpayKey !== '') {
await updateOption('EpayKey', inputs.EpayKey); await updateOption('EpayKey', inputs.EpayKey);
}
await updateOption('Price', "" + inputs.Price); await updateOption('Price', "" + inputs.Price);
}; };