Files
labelmain-demo/components/login/libs/session.ts
2026-04-23 14:47:14 +08:00

114 lines
2.9 KiB
TypeScript

"use server"
import redis from "./redis"
import { deleteCachedSession, getOrLoadSession } from "./session-cache"
import {
getClientIpFromRequest,
getSessionRedisKeyFromCookieValue,
SESSION_COOKIE_NAME,
} from "./session-common"
const roundDurationMs = (durationMs: number) =>
Math.round(durationMs * 100) / 100
// 校验用户信息
export async function genAccessToken(req: any) {
const sessionLookupStart = performance.now()
let redisLookupMs = 0
let sessionSource: "memory" | "shared" | "redis" | "skip" = "skip"
try {
const sessionData = req?.cookies?.get?.(SESSION_COOKIE_NAME)?.value
const redisKey = getSessionRedisKeyFromCookieValue(sessionData)
// 无session 直接重定向到登录页面
if (!redisKey) {
return {
ok: false as const,
message: "客户端请求中,未包含用户标识",
timing: {
sessionLookupMs: roundDurationMs(
performance.now() - sessionLookupStart
),
redisLookupMs: 0,
sessionSource,
},
}
}
const sessionResult = await getOrLoadSession(redisKey, async () => {
const redisLookupStart = performance.now()
const userDataString = await redis.get(redisKey)
redisLookupMs = roundDurationMs(performance.now() - redisLookupStart)
if (!userDataString) {
return null
}
return JSON.parse(userDataString)
})
sessionSource = sessionResult.source
// redis中无用户信息 直接重定向到登录页面
if (!sessionResult.data) {
deleteCachedSession(redisKey)
return {
ok: false as const,
message: "未获取到用户信息",
timing: {
sessionLookupMs: roundDurationMs(
performance.now() - sessionLookupStart
),
redisLookupMs,
sessionSource,
},
}
}
const userData = sessionResult.data
const clientIP = getClientIpFromRequest(req)
if (clientIP !== userData?.clientIP) {
return {
ok: false as const,
message: `客户端信息与缓存用户信息不一致 \n 客户端: ${clientIP} | redis存储: ${userData?.clientIP}`,
timing: {
sessionLookupMs: roundDurationMs(
performance.now() - sessionLookupStart
),
redisLookupMs,
sessionSource,
},
}
}
return {
ok: true as const,
userData: {
...userData,
redisKey,
},
timing: {
sessionLookupMs: roundDurationMs(
performance.now() - sessionLookupStart
),
redisLookupMs,
sessionSource,
},
}
} catch (err: any) {
return {
ok: false as const,
message: `获取用户信息报错, 报错原因:${err?.message}`,
timing: {
sessionLookupMs: roundDurationMs(
performance.now() - sessionLookupStart
),
redisLookupMs,
sessionSource,
},
}
}
}