sso-login调整

This commit is contained in:
2026-08-27 16:37:33 +08:00
parent 2d19c736a6
commit 989120cab8
4 changed files with 291 additions and 67 deletions
+2 -2
View File
@@ -139,13 +139,13 @@ export default function HomePage() {
color: '#04121f',
background: 'linear-gradient(135deg, #00d4ff, #4f9eff)',
}}>
{userInfo.userId.charAt(0).toUpperCase()}
{(userInfo.userName ?? userInfo.userId).charAt(0).toUpperCase()}
</div>
<span style={{
fontSize: 13,
...(isDark ? { color: 'rgba(168,216,255,0.85)' } : { color: '#334155' }),
}}>
{userInfo.userId}
{userInfo.userName ?? userInfo.userId}
</span>
<button
onClick={handleLogout}
+4 -27
View File
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { User, Lock, Building2, LogIn, AlertCircle, Loader2 } from 'lucide-react';
import { User, Lock, LogIn, AlertCircle, Loader2 } from 'lucide-react';
import StarBackground from '@/shared/components/StarBackground';
import { iamLogin, saveSession } from '@/shared/services/iamAuth';
import { useTheme } from '@/shared/context/ThemeContext';
@@ -33,7 +33,6 @@ export default function LoginPage() {
const [userId, setUserId] = useState('');
const [password, setPassword] = useState('');
const [tenantId, setTenantId] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
@@ -51,12 +50,8 @@ export default function LoginPage() {
setLoading(true);
setError('');
try {
const result = await iamLogin({ userId: userId.trim(), password, tenantId: tenantId.trim() || undefined });
saveSession(result.token, {
userId: result.userId,
tenantId: result.tenantId,
loginTime: new Date().toLocaleString('zh-CN'),
});
const result = await iamLogin({ userId: userId.trim(), password });
saveSession(result.token, result.userInfo);
navigate('/', { replace: true });
} catch (ex) {
setError(ex instanceof Error ? ex.message : '登录失败,请稍后重试');
@@ -138,7 +133,7 @@ export default function LoginPage() {
</div>
</div>
<div style={{ marginBottom: 16 }}>
<div style={{ marginBottom: 20 }}>
<label style={{ display: 'block', fontSize: 13, marginBottom: 6, color: isDark ? 'rgba(168,216,255,0.8)' : '#475569' }}>
密码
</label>
@@ -157,24 +152,6 @@ export default function LoginPage() {
</div>
</div>
<div style={{ marginBottom: 20 }}>
<label style={{ display: 'block', fontSize: 13, marginBottom: 6, color: isDark ? 'rgba(168,216,255,0.8)' : '#475569' }}>
租户 ID(可选)
</label>
<div style={{ position: 'relative' }}>
<Building2 size={16} style={iconStyle(isDark)} />
<input
type="text"
value={tenantId}
onChange={(e) => setTenantId(e.target.value)}
placeholder="不填则自动匹配已授权租户"
style={inputStyle(isDark)}
onFocus={(e) => { e.currentTarget.style.borderColor = '#00d4ff'; }}
onBlur={(e) => { e.currentTarget.style.borderColor = isDark ? 'rgba(0,212,255,0.25)' : 'rgba(0,0,0,0.12)'; }}
/>
</div>
</div>
{error && (
<div style={{
display: 'flex', alignItems: 'center', gap: 8,
+64 -6
View File
@@ -1,21 +1,47 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { Spin } from 'antd';
import { AlertCircle } from 'lucide-react';
import { iamSsoLogin, saveSession } from '@/shared/services/iamAuth';
/**
* SSO 登录回调入口
* 接收 URL 参数 userToken,写入 sessionStorage 后跳转首页
*
* 流程:
* 1. 从 URL 参数获取 userToken
* 2. 调用 iamSsoLogin 完成:
* - POST /identity/token/refresh/app 刷新应用 token + 用户信息
* - POST /identity/login/info 获取登录详情
* - POST /tenant?appId=APPID 拉取租户列表,选默认租户
* - POST /identity/token/refresh/tenant 切换租户刷新 token
* 3. userInfo 写入 sessionStorage,跳转首页
*/
const SSOLogin: React.FC = () => {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const [error, setError] = useState<string>('');
useEffect(() => {
const userToken = searchParams.get('userToken');
if (userToken) {
sessionStorage.setItem('userToken', userToken);
if (!userToken) {
setError('URL 缺少 userToken 参数');
return;
}
navigate('/', { replace: true });
let cancelled = false;
(async () => {
try {
const result = await iamSsoLogin(userToken);
if (cancelled) return;
saveSession(result.token, result.userInfo);
navigate('/', { replace: true });
} catch (ex) {
if (cancelled) return;
setError(ex instanceof Error ? ex.message : 'SSO 登录失败');
}
})();
return () => { cancelled = true; };
}, [searchParams, navigate]);
return (
@@ -26,8 +52,40 @@ const SSOLogin: React.FC = () => {
alignItems: 'center',
justifyContent: 'center',
background: '#0a1628',
color: '#a8d8ff',
fontFamily: "-apple-system, 'SF Pro Display', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif",
}}>
<Spin size="large" tip="正在登录..." />
{error ? (
<div style={{
display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16,
padding: '32px 40px',
borderRadius: 16,
background: 'rgba(239,68,68,0.08)',
border: '1px solid rgba(239,68,68,0.4)',
maxWidth: 460,
}}>
<AlertCircle size={36} color="#fca5a5" />
<div style={{ fontSize: 16, fontWeight: 600, color: '#fca5a5' }}>SSO 登录失败</div>
<div style={{ fontSize: 13, color: 'rgba(168,216,255,0.7)', textAlign: 'center', wordBreak: 'break-all' }}>
{error}
</div>
<button
onClick={() => navigate('/login', { replace: true })}
style={{
marginTop: 8, padding: '8px 20px', borderRadius: 8,
border: '1px solid rgba(0,212,255,0.4)', background: 'rgba(0,212,255,0.1)',
color: '#00d4ff', fontSize: 13, cursor: 'pointer',
}}
>
前往登录页
</button>
</div>
) : (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16 }}>
<Spin size="large" />
<div style={{ fontSize: 14, color: 'rgba(168,216,255,0.7)' }}>正在登录...</div>
</div>
)}
</div>
);
};