From 30c15b81350b9c543f6438400adf39c4f5340917 Mon Sep 17 00:00:00 2001 From: DacongDA Date: Sat, 26 Jul 2025 23:26:37 +0800 Subject: [PATCH] feat: fix the error effect of form post response type (#4003) --- web/src/Setting.js | 21 +++++++++++++++ web/src/auth/AuthCallback.js | 50 +++++++++++++++--------------------- web/src/auth/LoginPage.js | 19 +++++++++++--- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/web/src/Setting.js b/web/src/Setting.js index 85a719b7..f95f45f5 100644 --- a/web/src/Setting.js +++ b/web/src/Setting.js @@ -1816,3 +1816,24 @@ export function renderLoginPanel(application, getInnerComponent, componentThis) ); } + +export function createFormAndSubmit(url, params) { + const form = document.createElement("form"); + form.method = "post"; + form.action = url; + + for (const k in params) { + if (!params[k]) { + continue; + } + const input = document.createElement("input"); + input.type = "hidden"; + input.name = k; + input.value = params[k]; + form.appendChild(input); + } + + document.body.appendChild(form); + form.submit(); + setTimeout(() => {form.remove();}, 500); +} diff --git a/web/src/auth/AuthCallback.js b/web/src/auth/AuthCallback.js index 36042914..cbc3a7bb 100644 --- a/web/src/auth/AuthCallback.js +++ b/web/src/auth/AuthCallback.js @@ -21,7 +21,7 @@ import {authConfig} from "./Auth"; import * as Setting from "../Setting"; import i18next from "i18next"; import RedirectForm from "../common/RedirectForm"; -import {renderLoginPanel} from "../Setting"; +import {createFormAndSubmit, renderLoginPanel} from "../Setting"; class AuthCallback extends React.Component { constructor(props) { @@ -35,30 +35,6 @@ class AuthCallback extends React.Component { }; } - submitFormPost(redirectUri, code, state) { - const form = document.createElement("form"); - form.method = "post"; - form.action = redirectUri; - - const codeInput = document.createElement("input"); - codeInput.type = "hidden"; - codeInput.name = "code"; - codeInput.value = code; - form.appendChild(codeInput); - - if (state) { - const stateInput = document.createElement("input"); - stateInput.type = "hidden"; - stateInput.name = "state"; - stateInput.value = state; - form.appendChild(stateInput); - } - - document.body.appendChild(form); - form.submit(); - setTimeout(() => form.remove(), 1000); - } - getInnerParams() { // For example, for Casbin-OA, realRedirectUri = "http://localhost:9000/login" // realRedirectUrl = "http://localhost:9000" @@ -189,6 +165,7 @@ class AuthCallback extends React.Component { .then((res) => { if (res.status === "ok") { const responseType = this.getResponseType(); + const responseTypes = responseType.split(" "); const handleLogin = (res) => { if (responseType === "login") { if (res.data3) { @@ -208,20 +185,35 @@ class AuthCallback extends React.Component { } if (responseMode === "form_post") { - this.submitFormPost(oAuthParams?.redirectUri, res.data, oAuthParams?.state); + const params = { + code: res.data, + state: oAuthParams?.state, + }; + createFormAndSubmit(oAuthParams?.redirectUri, params); } else { const code = res.data; Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`); } // Setting.showMessage("success", `Authorization code: ${res.data}`); - } else if (responseType === "token" || responseType === "id_token") { + } else if (responseTypes.includes("token") || responseTypes.includes("id_token")) { if (res.data3) { sessionStorage.setItem("signinUrl", signinUrl); Setting.goToLinkSoft(this, `/forget/${applicationName}`); return; } - const token = res.data; - Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`); + + if (responseMode === "form_post") { + const params = { + token: responseTypes.includes("token") ? res.data : null, + id_token: responseTypes.includes("id_token") ? res.data : null, + token_type: "bearer", + state: oAuthParams?.state, + }; + createFormAndSubmit(oAuthParams?.redirectUri, params); + } else { + const token = res.data; + Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`); + } } else if (responseType === "link") { let from = innerParams.get("from"); const oauth = innerParams.get("oauth"); diff --git a/web/src/auth/LoginPage.js b/web/src/auth/LoginPage.js index d2e0bf60..d692504a 100644 --- a/web/src/auth/LoginPage.js +++ b/web/src/auth/LoginPage.js @@ -37,7 +37,7 @@ import RedirectForm from "../common/RedirectForm"; import {RequiredMfa} from "./mfa/MfaAuthVerifyForm"; import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton"; import * as ProviderButton from "./ProviderButton"; -import {goToLink} from "../Setting"; +import {createFormAndSubmit, goToLink} from "../Setting"; import WeChatLoginPanel from "./WeChatLoginPanel"; const FaceRecognitionCommonModal = lazy(() => import("../common/modal/FaceRecognitionCommonModal")); const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal")); @@ -503,7 +503,8 @@ class LoginPage extends React.Component { .then((res) => { const loginHandler = (res) => { const responseType = values["type"]; - + const responseTypes = responseType.split(" "); + const responseMode = oAuthParams?.responseMode || "query"; if (responseType === "login") { if (res.data3) { sessionStorage.setItem("signinUrl", window.location.pathname + window.location.search); @@ -518,14 +519,24 @@ class LoginPage extends React.Component { this.setState({ userCodeStatus: "success", }); - } else if (responseType === "token" || responseType === "id_token") { + } else if (responseTypes.includes("token") || responseTypes.includes("id_token")) { if (res.data3) { sessionStorage.setItem("signinUrl", window.location.pathname + window.location.search); Setting.goToLinkSoft(this, `/forget/${this.state.applicationName}`); } const amendatoryResponseType = responseType === "token" ? "access_token" : responseType; const accessToken = res.data; - Setting.goToLink(`${oAuthParams.redirectUri}#${amendatoryResponseType}=${accessToken}&state=${oAuthParams.state}&token_type=bearer`); + if (responseMode === "form_post") { + const params = { + token: responseTypes.includes("token") ? res.data : null, + id_token: responseTypes.includes("id_token") ? res.data : null, + token_type: "bearer", + state: oAuthParams?.state, + }; + createFormAndSubmit(oAuthParams?.redirectUri, params); + } else { + Setting.goToLink(`${oAuthParams.redirectUri}#${amendatoryResponseType}=${accessToken}&state=${oAuthParams.state}&token_type=bearer`); + } } else if (responseType === "saml") { if (res.data === RequiredMfa) { this.props.onLoginSuccess(window.location.href);