fix(登录): redirect 透传登录 URL 其余 query 到目标页

?redirect=/page/strategy/dashboard-agent&taskId=3334 时把 taskId 等非登录消费参数
透传到目标页 query(目标自带同名参数优先),鉴权类参数不透传以防泄漏到地址栏。
修复跳转后目标页「缺少 taskId」。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
fengxiangdebaoziandClaude Opus 4.8 committed 2026-06-23 22:10:40 +08:00
1 parent e3631a9fd6
commit f551c7af9b
1 file changed
+20 -1
+20 -1
View File
@@ -87,11 +87,30 @@ export default function LoginPage() {
// 优先级最高:显式指定即按它跳,先于 taskId/goPath 深链与默认首页。出于安全只接受**站内
// 相对路径**:拒绝带协议的绝对 URL(http(s):、javascript: 等)、协议相对 URL(//host)与反斜杠,
// 避免开放式跳转;缺前导斜杠时自动补全。
//
// 参数透传:登录 URL 上「非登录自身消费」的其余 query(如 taskId / hideChrome)会被透传到
// 目标页 query——这样 `?redirect=/page/strategy/dashboard-agent&taskId=3334` 也能让目标页拿到
// taskId,无需把它编进 redirect 值里。目标已自带的同名参数优先(不覆盖);登录鉴权类参数
// (token/authToken/ticket 等)一律**不透传**,避免泄漏到应用页地址栏。
const redirectTo = useMemo(() => {
const raw = searchParams.get('redirect')?.trim() ?? '';
if (!raw) return '';
if (/^[a-z][a-z0-9+.-]*:/i.test(raw) || raw.startsWith('//') || raw.includes('\\')) return '';
return raw.startsWith('/') ? raw : `/${raw}`;
const normalized = raw.startsWith('/') ? raw : `/${raw}`;
const [pathOnly, ownQuery = ''] = normalized.split('?');
const target = new URLSearchParams(ownQuery);
// 登录流程自身消费的参数,不透传到目标页(尤以鉴权类为甚)。
const LOGIN_OWNED = new Set([
'redirect', 'ticket', 'userId', 'env', 'theme', 'yUserId',
'token', 'access_token', 'password', 'authToken', 'goPath', 'from',
]);
new URLSearchParams(searchParams.toString()).forEach((value, key) => {
if (LOGIN_OWNED.has(key)) return;
if (target.has(key)) return; // 目标自带优先
target.set(key, value);
});
const qs = target.toString();
return qs ? `${pathOnly}?${qs}` : pathOnly;
}, [searchParams]);
const externalParams = useMemo(
() => ({