提供北京大学统一认证支持,仅需配置环境变量

This commit is contained in:
2026-03-18 08:57:47 +08:00
parent a6ae3b8845
commit b9c83617ad
7 changed files with 502 additions and 147 deletions

View File

@@ -6,6 +6,36 @@ import bcrypt from "bcryptjs"
import { db } from "./db"
import { clearSessionInvalidation, isSessionInvalidated } from "./service/session"
/** 用户查询时需要 include 的关联 */
export const userAuthInclude = {
roles: { include: { permissions: true } },
dept: true,
} as const
/** 从数据库用户对象构建 JWT payload供密码登录和 IAAA 登录共用) */
export function buildUserJwtPayload(user: {
id: string
name: string | null
status: string | null
deptCode: string | null
isSuperAdmin: boolean
roles: Array<{ name: string; permissions: Array<{ name: string }> }>
}) {
const roles = user.roles.map((r) => r.name)
const permissions = Array.from(
new Set(user.roles.flatMap((r) => r.permissions.map((p) => p.name)))
)
return {
id: user.id,
name: user.name,
status: user.status,
deptCode: user.deptCode,
roles,
permissions,
isSuperAdmin: user.isSuperAdmin,
}
}
export const authOptions: NextAuthOptions = {
providers: [
CredentialsProvider({
@@ -22,15 +52,8 @@ export const authOptions: NextAuthOptions = {
try {
// 查找用户
const user = await db.user.findUnique({
where: {
id: credentials.id
},
include: {
roles: {
include: { permissions: true }
},
dept: true
}
where: { id: credentials.id },
include: userAuthInclude,
})
if (!user) {
@@ -39,7 +62,6 @@ export const authOptions: NextAuthOptions = {
// 验证密码
const isPasswordValid = await bcrypt.compare(credentials.password, user.password)
if (!isPasswordValid) {
return null
@@ -53,23 +75,8 @@ export const authOptions: NextAuthOptions = {
// 清除会话失效标记(用户已重新登录,获得最新权限)
await clearSessionInvalidation(user.id)
// 返回用户信息、角色和权限
const roles = user.roles.map((r) => r.name)
const permissions = Array.from(
new Set(user.roles.flatMap((r) =>
r.permissions.map((p) => p.name)
))
)
return {
id: user.id,
name: user.name,
status: user.status,
deptCode: user.deptCode,
roles,
permissions,
isSuperAdmin: user.isSuperAdmin
} as any
return buildUserJwtPayload(user) as any
} catch (error) {
console.error("Auth error:", error)
return null