From b1630f0d1c468b9eb64a1d6120ec000fd852ca04 Mon Sep 17 00:00:00 2001
From: ckt1031 <65409152+ckt1031@users.noreply.github.com>
Date: Sun, 17 Sep 2023 22:25:44 +0800
Subject: [PATCH] fix: github oauth
---
controller/github.go | 27 +++++++++++++++++++++++++++
router/api-router.go | 1 +
web/src/components/GitHubOAuth.js | 9 +++++----
web/src/components/LoginForm.js | 3 ++-
web/src/components/PersonalSetting.js | 3 ++-
web/src/components/utils.js | 20 ++++++++++++++++++++
6 files changed, 57 insertions(+), 6 deletions(-)
create mode 100644 web/src/components/utils.js
diff --git a/controller/github.go b/controller/github.go
index e1c64130..ee995379 100644
--- a/controller/github.go
+++ b/controller/github.go
@@ -79,6 +79,14 @@ func getGitHubUserInfoByCode(code string) (*GitHubUser, error) {
func GitHubOAuth(c *gin.Context) {
session := sessions.Default(c)
+ state := c.Query("state")
+ if state == "" || session.Get("oauth_state") == nil || state != session.Get("oauth_state").(string) {
+ c.JSON(http.StatusForbidden, gin.H{
+ "success": false,
+ "message": "state is empty or not same",
+ })
+ return
+ }
username := session.Get("username")
if username != nil {
GitHubBind(c)
@@ -205,3 +213,22 @@ func GitHubBind(c *gin.Context) {
})
return
}
+
+func GenerateOAuthCode(c *gin.Context) {
+ session := sessions.Default(c)
+ state := common.GetRandomString(12)
+ session.Set("oauth_state", state)
+ err := session.Save()
+ if err != nil {
+ c.JSON(http.StatusOK, gin.H{
+ "success": false,
+ "message": err.Error(),
+ })
+ return
+ }
+ c.JSON(http.StatusOK, gin.H{
+ "success": true,
+ "message": "",
+ "data": state,
+ })
+}
diff --git a/router/api-router.go b/router/api-router.go
index dad417b1..7e64a3bf 100644
--- a/router/api-router.go
+++ b/router/api-router.go
@@ -22,6 +22,7 @@ func SetApiRouter(router *gin.Engine) {
apiRouter.POST("/user/reset", middleware.CriticalRateLimit(), controller.ResetPassword)
apiRouter.GET("/oauth/github", middleware.CriticalRateLimit(), controller.GitHubOAuth)
apiRouter.GET("/oauth/discord", middleware.CriticalRateLimit(), controller.DiscordOAuth)
+ apiRouter.GET("/oauth/state", middleware.CriticalRateLimit(), controller.GenerateOAuthCode)
apiRouter.GET("/oauth/wechat", middleware.CriticalRateLimit(), controller.WeChatAuth)
apiRouter.GET("/oauth/google", middleware.CriticalRateLimit(), controller.GoogleOAuth)
apiRouter.GET("/oauth/wechat/bind", middleware.CriticalRateLimit(), middleware.UserAuth(), controller.WeChatBind)
diff --git a/web/src/components/GitHubOAuth.js b/web/src/components/GitHubOAuth.js
index 147d4d30..c43ed2a1 100644
--- a/web/src/components/GitHubOAuth.js
+++ b/web/src/components/GitHubOAuth.js
@@ -13,8 +13,8 @@ const GitHubOAuth = () => {
let navigate = useNavigate();
- const sendCode = async (code, count) => {
- const res = await API.get(`/api/oauth/github?code=${code}`);
+ const sendCode = async (code, state, count) => {
+ const res = await API.get(`/api/oauth/github?code=${code}&state=${state}`);
const { success, message, data } = res.data;
if (success) {
if (message === 'bind') {
@@ -36,13 +36,14 @@ const GitHubOAuth = () => {
count++;
setPrompt(`出现错误,第 ${count} 次重试中...`);
await new Promise((resolve) => setTimeout(resolve, count * 2000));
- await sendCode(code, count);
+ await sendCode(code, state, count);
}
};
useEffect(() => {
let code = searchParams.get('code');
- sendCode(code, 0).then();
+ let state = searchParams.get('state');
+ sendCode(code, state, 0).then();
}, []);
return (
diff --git a/web/src/components/LoginForm.js b/web/src/components/LoginForm.js
index 46664323..50dd5fec 100644
--- a/web/src/components/LoginForm.js
+++ b/web/src/components/LoginForm.js
@@ -4,6 +4,7 @@ import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { UserContext } from '../context/User';
import { API, getLogo, showError, showInfo, showSuccess } from '../helpers';
import Turnstile from 'react-turnstile';
+import { getOAuthState, onGitHubOAuthClicked } from './utils';stream/main
const LoginForm = () => {
const [inputs, setInputs] = useState({
@@ -175,7 +176,7 @@ const LoginForm = () => {
circular
color='black'
icon='github'
- onClick={onGitHubOAuthClicked}
+ onClick={()=>onGitHubOAuthClicked(status.github_client_id)}
/>
)}
{status.wechat_login && (
diff --git a/web/src/components/PersonalSetting.js b/web/src/components/PersonalSetting.js
index deb5a38b..1f637e83 100644
--- a/web/src/components/PersonalSetting.js
+++ b/web/src/components/PersonalSetting.js
@@ -4,6 +4,7 @@ import { Link, useNavigate } from 'react-router-dom';
import { API, copy, showError, showInfo, showNotice, showSuccess } from '../helpers';
import Turnstile from 'react-turnstile';
import { UserContext } from '../context/User';
+import { onGitHubOAuthClicked } from './utils';
const PersonalSetting = () => {
const [userState, userDispatch] = useContext(UserContext);
@@ -265,7 +266,7 @@ const PersonalSetting = () => {
{
status.github_oauth && (
-
+
)
}
{
diff --git a/web/src/components/utils.js b/web/src/components/utils.js
new file mode 100644
index 00000000..5363ba5e
--- /dev/null
+++ b/web/src/components/utils.js
@@ -0,0 +1,20 @@
+import { API, showError } from '../helpers';
+
+export async function getOAuthState() {
+ const res = await API.get('/api/oauth/state');
+ const { success, message, data } = res.data;
+ if (success) {
+ return data;
+ } else {
+ showError(message);
+ return '';
+ }
+}
+
+export async function onGitHubOAuthClicked(github_client_id) {
+ const state = await getOAuthState();
+ if (!state) return;
+ window.open(
+ `https://github.com/login/oauth/authorize?client_id=${github_client_id}&state=${state}&scope=user:email`
+ );
+}
\ No newline at end of file