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:
65
app/api/callback/route.ts
Normal file
65
app/api/callback/route.ts
Normal 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 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user