perf(session): ttl

This commit is contained in:
zhangheng
2026-04-23 14:47:14 +08:00
parent cd1bad6da9
commit 5b38f684c3
6 changed files with 488 additions and 222 deletions

View File

@@ -1,6 +1,14 @@
import { Login } from "@/components/login/api/types"
import redis from "@/components/login/libs/redis"
import { encrypt, generateKeyFromEnv } from "@/components/login/libs/session"
import {
deleteCachedSession,
setCachedSession,
} from "@/components/login/libs/session-cache"
import {
createSessionRedisKey,
getSessionRedisKeyFromCookieValue,
SESSION_COOKIE_NAME,
} from "@/components/login/libs/session-common"
import { cookies } from "next/headers"
export const handleLoginData = async (props: {
@@ -10,36 +18,36 @@ export const handleLoginData = async (props: {
}) => {
const { clientIP, fingerprint, data } = props
const sessionKey = {
clientIP,
fingerprint: fingerprint,
}
const cookieStore = await cookies()
const oldSession = cookieStore.get("session")?.value || ""
if (oldSession) {
redis.del(JSON.parse(oldSession) as any)
const oldSessionKey = getSessionRedisKeyFromCookieValue(
cookieStore.get(SESSION_COOKIE_NAME)?.value
)
if (oldSessionKey) {
await redis.del(oldSessionKey)
deleteCachedSession(oldSessionKey)
}
const key = await generateKeyFromEnv(process.env.ENCRYPTION_KEY || "")
const encryptedSessionData = await encrypt(JSON.stringify(sessionKey), key)
const sessionRedisKey = createSessionRedisKey()
const sessionUserData = {
clientIP,
fingerprint: fingerprint,
user_name: data?.name,
access_token: data.token,
refresh_token: data.refresh_token,
}
// save redis
await redis.set(
encryptedSessionData,
JSON.stringify({
clientIP,
fingerprint: fingerprint,
user_name: data?.name,
access_token: data.token,
refresh_token: data.refresh_token,
}),
sessionRedisKey,
JSON.stringify(sessionUserData),
"EX",
172800
)
setCachedSession(sessionRedisKey, sessionUserData)
// set cookie
cookieStore.set("session", JSON.stringify(encryptedSessionData), {
cookieStore.set(SESSION_COOKIE_NAME, sessionRedisKey, {
httpOnly: true,
secure: process.env.NEXT_PUBLIC_COOKIE_ENV === "production",
maxAge: 60 * 60 * 24 * 30, // 30天
@@ -59,17 +67,26 @@ export const handleRefreshToken = async (props: {
}) => {
const { userData, data } = props
const { redisKey, ...rest } = userData
const sessionRedisKey = getSessionRedisKeyFromCookieValue(redisKey)
if (!sessionRedisKey) {
throw new Error("未获取到有效的 session key")
}
const sessionUserData = {
...rest,
user_name: data?.name,
access_token: data.token,
refresh_token: data.refresh_token,
}
await redis.set(
JSON.parse(redisKey),
JSON.stringify({
...rest,
user_name: data?.name,
access_token: data.token,
refresh_token: data.refresh_token,
}),
sessionRedisKey,
JSON.stringify(sessionUserData),
"EX",
172800
)
setCachedSession(sessionRedisKey, sessionUserData)
return {
...data,
token: "",
@@ -80,11 +97,16 @@ export const handleRefreshToken = async (props: {
export const handleDeleteCookie = async () => {
const cookieStore = await cookies()
const sessionData = cookieStore.get("session")?.value || ""
const sessionData = cookieStore.get(SESSION_COOKIE_NAME)?.value || ""
const sessionRedisKey = getSessionRedisKeyFromCookieValue(sessionData)
// 删cookie和redis中用户
if (sessionRedisKey) {
await redis.del(sessionRedisKey)
deleteCachedSession(sessionRedisKey)
}
if (sessionData) {
await redis.del(JSON.parse(sessionData) as any)
cookieStore.delete("session")
cookieStore.delete(SESSION_COOKIE_NAME)
}
}