58 lines
1.6 KiB
JavaScript
58 lines
1.6 KiB
JavaScript
import session from "express-session";
|
|
import { createClient } from "redis";
|
|
|
|
|
|
export async function createRedisSession({
|
|
redisUrl = process.env.REDIS_URL,
|
|
cookieName = process.env.SESSION_COOKIE_NAME || "sc.sid",
|
|
secret = process.env.SESSION_SECRET,
|
|
trustProxy = process.env.TRUST_PROXY === "1",
|
|
ttlSeconds = 60 * 60 * 12, // 12h
|
|
} = {}) {
|
|
if (!redisUrl) throw new Error("REDIS_URL no definido");
|
|
if (!secret) throw new Error("SESSION_SECRET no definido");
|
|
|
|
|
|
const redis = createClient({ url: redisUrl });
|
|
redis.on("error", (err) => console.error("[Redis]", err));
|
|
await redis.connect();
|
|
console.log("[Redis] conectado");
|
|
|
|
|
|
// Resolver RedisStore (v5 / v6 / v7)
|
|
async function resolveRedisStore() {
|
|
const mod = await import("connect-redis");
|
|
// v6/v7: named export class
|
|
if (typeof mod.RedisStore === "function") return mod.RedisStore;
|
|
// v5: default factory connectRedis(session)
|
|
if (typeof mod.default === "function") {
|
|
const maybe = mod.default;
|
|
if (maybe.prototype && (maybe.prototype.get || maybe.prototype.set)) return maybe; // clase
|
|
const factory = mod.default(session);
|
|
return factory;
|
|
}
|
|
throw new Error("No se pudo resolver RedisStore de connect-redis");
|
|
}
|
|
|
|
|
|
const RedisStore = await resolveRedisStore();
|
|
const store = new RedisStore({ client: redis, prefix: "sc:sess:", ttl: ttlSeconds });
|
|
|
|
|
|
const sessionMw = session({
|
|
name: cookieName,
|
|
secret,
|
|
resave: false,
|
|
saveUninitialized: false,
|
|
store,
|
|
cookie: {
|
|
httpOnly: true,
|
|
sameSite: "lax",
|
|
secure: process.env.NODE_ENV === "production", // requiere https
|
|
maxAge: ttlSeconds * 1000,
|
|
},
|
|
});
|
|
|
|
|
|
return { sessionMw, redis, store, trustProxy };
|
|
} |