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>
This commit is contained in:
54
app/api/auth/verify/route.ts
Normal file
54
app/api/auth/verify/route.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
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 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user