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>
66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
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 }
|
||
)
|
||
}
|
||
}
|