"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, }, } } }