Skip to content

Instantly share code, notes, and snippets.

@digitaldesigndj
Last active August 20, 2022 03:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digitaldesigndj/73daa4222ff685f77a1a0e84f3583cc4 to your computer and use it in GitHub Desktop.
Save digitaldesigndj/73daa4222ff685f77a1a0e84f3583cc4 to your computer and use it in GitHub Desktop.
Fresh Redis Session Middleware
// 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/std@0.152.0/",
// "redis": "https://deno.land/x/redis@v0.26.0/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