Last active
August 20, 2022 03:42
-
-
Save digitaldesigndj/73daa4222ff685f77a1a0e84f3583cc4 to your computer and use it in GitHub Desktop.
Fresh Redis Session Middleware
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// routes/_middleware.js | |
import { cyan, green, yellow } from "$std/fmt/colors.ts"; | |
import { getCookies, setCookie } from "$std/http/cookie.ts"; | |
import { config } from "$std/dotenv/mod.ts"; | |
import * as redis from "redis"; | |
// import_map.json | |
// "@/": "./", | |
// "$std/": "https://deno.land/[email protected]/", | |
// "redis": "https://deno.land/x/[email protected]/mod.ts", | |
// Load dotenv over Deno.env | |
const env = Object.assign(Deno.env.toObject(), await config()); | |
const { REDIS_PASS, REDIS_HOST, REDIS_PORT, API_URL, DENO_ENV } = env; | |
const COOKIE_NAME = "uuid"; | |
const store = await redis.connect({ | |
password: REDIS_PASS, | |
hostname: REDIS_HOST, | |
port: REDIS_PORT, | |
}); | |
// Session Tracker | |
const createSession = async () => { | |
const session = { | |
cart: [], | |
}; | |
session[COOKIE_NAME] = crypto.randomUUID() | |
await store.set(session[COOKIE_NAME], JSON.stringify(session)); | |
await store.expire(session[COOKIE_NAME], 7 * 24 * 60 * 60); | |
return session; | |
}; | |
const setupSession = async (req, ctx) => { | |
const cookies = getCookies(req.headers); | |
let tracker_id = cookies[COOKIE_NAME]; | |
if (tracker_id) { | |
const session = await store.get(tracker_id); | |
if (session) { | |
ctx.state = JSON.parse(session); | |
} else { | |
tracker_id = false; | |
ctx.state = await createSession(); | |
} | |
} else { | |
ctx.state = await createSession(); | |
} | |
if (!tracker_id) { | |
const resp = await ctx.next(); | |
setCookie(resp.headers, { name: COOKIE_NAME, value: ctx.state[COOKIE_NAME] }); | |
return resp; | |
} else { | |
return await ctx.next(); | |
} | |
}; | |
export async function handler(req, ctx) { | |
// Logging | |
const start = Date.now(); | |
const { pathname } = new URL(req.url); | |
const withSession = [ | |
"/", | |
"/pages", | |
"/with", | |
"/sessions", | |
"/here", | |
"/middleware", | |
"/runs/always", | |
]; | |
let resp; | |
if ( | |
withSession.includes(pathname) || | |
pathname.startsWith("/api/") || | |
pathname.startsWith("/scans/") | |
) { | |
ctx.API_URL = API_URL; | |
ctx.DENO_ENV = DENO_ENV; | |
ctx.store = store; | |
resp = await setupSession(req, ctx); | |
} else { | |
resp = await ctx.next(); | |
} | |
// Timing stuff - from oak | |
const ms = Date.now() - start; | |
resp.headers.set("X-Response-Time", `${ms}ms`); | |
// console.log( ms, req ) | |
console.log( | |
`${green(req.method)} ${cyan(pathname)} - ${yellow(String(ms) + "ms")}`, | |
); | |
return resp; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment