chore: initial commit of external-app SSO consumer

Next.js sample application that integrates with the mock SSO service:
redirects to sso-mock for login, receives the one-time sso_code on its
/callback route, and exchanges it for user info to establish a session.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
zhangheng
2026-07-06 18:11:23 +08:00
commit f737603b0c
14 changed files with 1639 additions and 0 deletions

65
app/api/callback/route.ts Normal file
View File

@@ -0,0 +1,65 @@
import { NextResponse } from 'next/server'
/**
* SSO 回调接口
* 接收 sso_code调用 Mock SSO 验证接口换取用户信息,
* 然后将用户信息写入 Cookie。
*/
export async function POST(req: Request) {
try {
const { code } = await req.json()
if (!code) {
return NextResponse.json({ error: '缺少 code 参数' }, { status: 400 })
}
// 调用 Mock SSO 的验证接口
const ssoUrl = process.env.SSO_URL || 'http://localhost:5501'
const verifyRes = await fetch(`${ssoUrl}/api/auth/verify`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code }),
})
if (!verifyRes.ok) {
const errData = await verifyRes.json().catch(() => ({}))
return NextResponse.json(
{ error: errData.error || 'SSO 验证失败' },
{ status: 401 }
)
}
const ssoData = await verifyRes.json()
const { token, refresh_token, user, permissions } = ssoData
// 将用户信息和 token 写入 Cookie
const response = NextResponse.json({ success: true })
response.cookies.set('user', JSON.stringify(user), {
httpOnly: false, // 客户端需要读取用于展示
path: '/',
maxAge: 86400,
})
response.cookies.set('token', token, {
httpOnly: true,
path: '/',
maxAge: 86400,
})
if (refresh_token) {
response.cookies.set('refresh_token', refresh_token, {
httpOnly: true,
path: '/',
maxAge: 86400 * 7,
})
}
return response
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || '回调处理失败' },
{ status: 500 }
)
}
}