Files
sso-portal/app/api/auth/verify/route.ts
zhangheng 37f10118d3 chore: initial commit of sso-mock SSO login service
Next.js + Mantine mock SSO service providing account/password, phone
verify-code, and Feishu QR login. Issues a one-time sso_code that the
external app exchanges for user info.

Includes:
- Feishu callback fix: guard against duplicate/concurrent /api/login
  submissions of the same single-use authorization code (feishuLogin
  once-guard + memoized onLoginSuccess to stop effect re-fire).
- ADAPTATION_GUIDE.md: how to switch from the in-memory code store to
  the real backend auth/index + inner_get_user_info endpoints.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 18:09:30 +08:00

55 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextResponse } from 'next/server'
import { codeStore } from '@/utils/code-store'
/**
* SSO Code 验证接口
*
* 外部应用拿到 sso_code 后,调用此接口换取用户信息。
* POST /api/auth/verify
* Body: { code: string }
*/
export async function POST(req: Request) {
try {
const { code } = await req.json()
if (!code) {
return NextResponse.json({ error: 'code 不能为空' }, { status: 400 })
}
const entry = codeStore.get(code)
if (!entry) {
return NextResponse.json({ error: 'code 无效或已过期' }, { status: 401 })
}
if (entry.expires < Date.now()) {
codeStore.delete(code)
return NextResponse.json({ error: 'code 已过期' }, { status: 401 })
}
// 验证通过,删除已使用的 code一次性
codeStore.delete(code)
// 返回用户信息和 token
const token =
'mock_token_' +
Math.random().toString(36).substring(2) +
'_' +
Date.now()
return NextResponse.json({
token,
refresh_token: 'mock_refresh_' + Date.now(),
user: entry.user,
permissions: [
{ object: '/dashboard', action: 'view' },
{ object: '/settings', action: 'view' },
],
})
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || '验证失败' },
{ status: 500 }
)
}
}