Skip to content

Instantly share code, notes, and snippets.

@justinnoel
Created November 12, 2022 12:34
Show Gist options
  • Save justinnoel/c04367b71d98e80dd11888d0a80f405e to your computer and use it in GitHub Desktop.
Save justinnoel/c04367b71d98e80dd11888d0a80f405e to your computer and use it in GitHub Desktop.
Configuring Sessions in Remix for Cloudflare Pages

Ref: https://discord.com/channels/595317990191398933/941119649783894016/1040772933687201802

How to setup sessions stored in Cloudflare KV using the Remix createCloudflareKVSessionStorage

server.js

Sets up the server to include access to sessionStorage and db on every request. These can then be accessed anywhere else in the code base using `context.

app_session.js

Configures createCloudflareKVSessionStorage to configure session cookies.

This file is really named app/session.js

login.ts

Abbreviated sample of an action storing information in a session.

check-email.ts

Sample of a loader reading info from a session

import {createCloudflareKVSessionStorage} from "@remix-run/cloudflare";
type SessionWrapperProps = {
kvNamespace: KVNamespace < string >;
sessionSecret: string;
};
export function sessionWrapper({kvNamespace, sessionSecret} : SessionWrapperProps) {
return createCloudflareKVSessionStorage({
kv: kvNamespace,
cookie: {
name: "SESSION",
httpOnly: true,
// Allow 7 day sessions
maxAge: 3600 * 24 * 7,
sameSite: "strict",
secure: true,
secrets: [sessionSecret]
}
});
}
import type {LoaderFunction}
from "@remix-run/cloudflare";
import type {CommonLoaderData}
from "~/types";
import {getCommonLoaderData} from "~/utils/general";
export type CheckEmailLoaderData = CommonLoaderData & {
loginEmail: string;
};
export const loader: LoaderFunction = async ({context, request}) : Promise < CheckEmailLoaderData > => {
const {getSession} = context.sessionStorage;
const session = await getSession(request ?. headers ?. get("Cookie"));
const loginEmail = session.get("login-email");
return {
...(await getCommonLoaderData({context, request})),
loginEmail
};
};
...
const {getSession, commitSession} = context.sessionStorage;
const session = await getSession(request ?. headers ?. get("Cookie"));
const expires = getDateInFuture({hours: 1});
session.flash("login-email", formData.email);
return redirect("/check-email", {
headers: {
"Set-Cookie": await commitSession(session, {expires})
}
});
...
import * as build from "@remix-run/dev/server-build";
import {createPagesFunctionHandler} from "@remix-run/cloudflare-pages";
import {sessionWrapper} from "app/sessions";
import {dbConnection} from "~/utils/database-connection";
const handleRequest = createPagesFunctionHandler({
build,
mode: (context) => {
return context;
},
getLoadContext: (context) => {
return {
env: context.env,
data: context.data,
sessionStorage: sessionWrapper(
{kvNamespace: context.env.KV_SESSIONS, sessionSecret: context.env.SESSION_SECRET}
),
db: dbConnection(
{host: context.env.PS_DB_HOST, password: context.env.PS_DB_PASSWORD, username: context.env.PS_DB_USERNAME}
)
};
}
});
export const onRequest = [handleRequest];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment