CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-remix-run--node

Node.js platform abstractions and utilities for Remix applications

Pending
Overview
Eval results
Files

cookie-session.mddocs/

Cookie and Session Implementations

Node.js-specific implementations of cookie and session utilities using cookie-signature for secure signing and various storage strategies.

Capabilities

Create Cookie

Creates a cookie with Node.js-specific signing using the cookie-signature library.

/**
 * Creates a cookie with Node.js-specific signing
 * @param name - The name of the cookie
 * @param cookieOptions - Configuration options for the cookie
 * @returns Cookie instance
 */
function createCookie(name: string, cookieOptions?: CookieOptions): Cookie;

Usage Examples:

import { createCookie } from "@remix-run/node";

// Basic cookie
const sessionCookie = createCookie("__session");

// Cookie with options
const secureCookie = createCookie("user-prefs", {
  maxAge: 86400, // 24 hours
  httpOnly: true,
  secure: process.env.NODE_ENV === "production",
  sameSite: "lax",
  secrets: ["cookie-secret-key"]
});

// Use in a Remix loader
export async function loader({ request }: LoaderFunctionArgs) {
  const cookieHeader = request.headers.get("Cookie");
  const userPrefs = await secureCookie.parse(cookieHeader);
  
  return json({ preferences: userPrefs });
}

// Use in a Remix action
export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const theme = formData.get("theme");
  
  return redirect("/", {
    headers: {
      "Set-Cookie": await secureCookie.serialize({ theme })
    }
  });
}

Create Cookie Session Storage

Creates cookie-based session storage where session data is stored in the cookie itself.

/**
 * Creates cookie-based session storage
 * @param options - Configuration options for cookie session storage
 * @returns SessionStorage instance that stores data in cookies
 */
function createCookieSessionStorage<Data = SessionData, FlashData = Data>(
  options: CookieSessionStorageOptions
): SessionStorage<Data, FlashData>;

Usage Examples:

import { createCookieSessionStorage } from "@remix-run/node";

// Basic cookie session storage
const sessionStorage = createCookieSessionStorage({
  cookie: {
    name: "__session",
    secrets: ["session-secret"],
    maxAge: 86400 // 24 hours
  }
});

// Advanced configuration
const sessionStorage = createCookieSessionStorage({
  cookie: {
    name: "__session",
    secrets: ["primary-secret", "fallback-secret"],
    maxAge: 86400,
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax",
    path: "/",
    domain: process.env.NODE_ENV === "production" ? ".example.com" : undefined
  }
});

// Use in authentication
export async function loader({ request }: LoaderFunctionArgs) {
  const session = await sessionStorage.getSession(
    request.headers.get("Cookie")
  );
  
  const userId = session.get("userId");
  const user = userId ? await getUserById(userId) : null;
  
  return json({ user });
}

export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const email = String(formData.get("email"));
  const password = String(formData.get("password"));
  
  const user = await authenticateUser(email, password);
  
  if (user) {
    const session = await sessionStorage.getSession();
    session.set("userId", user.id);
    
    return redirect("/dashboard", {
      headers: {
        "Set-Cookie": await sessionStorage.commitSession(session)
      }
    });
  }
  
  return json({ error: "Invalid credentials" }, { status: 400 });
}

Create Session Storage

Creates generic session storage with custom storage strategy.

/**
 * Creates session storage with custom storage strategy
 * @param options - Configuration options including storage strategy
 * @returns SessionStorage instance with custom storage
 */
function createSessionStorage<Data = SessionData, FlashData = Data>(
  options: SessionStorageOptions<Data, FlashData>
): SessionStorage<Data, FlashData>;

Usage Examples:

import { createSessionStorage } from "@remix-run/node";

// Custom database session storage
const databaseSessionStorage = createSessionStorage({
  cookie: {
    name: "__session",
    secrets: ["session-secret"],
    maxAge: 86400
  },
  async createData(data, expires) {
    const sessionId = generateId();
    await db.sessions.create({
      id: sessionId,
      data: JSON.stringify(data),
      expires
    });
    return sessionId;
  },
  async readData(id) {
    const session = await db.sessions.findUnique({ where: { id } });
    if (!session || (session.expires && session.expires < new Date())) {
      return null;
    }
    return JSON.parse(session.data);
  },
  async updateData(id, data, expires) {
    await db.sessions.update({
      where: { id },
      data: {
        data: JSON.stringify(data),
        expires
      }
    });
  },
  async deleteData(id) {
    await db.sessions.delete({ where: { id } });
  }
});

Create Memory Session Storage

Creates in-memory session storage for development and testing.

/**
 * Creates in-memory session storage
 * @param options - Optional configuration for memory session storage
 * @returns SessionStorage instance that stores data in memory
 */
function createMemorySessionStorage<Data = SessionData, FlashData = Data>(
  options?: MemorySessionStorageOptions
): SessionStorage<Data, FlashData>;

Usage Examples:

import { createMemorySessionStorage } from "@remix-run/node";

// Basic memory session storage
const sessionStorage = createMemorySessionStorage();

// With custom cookie configuration
const sessionStorage = createMemorySessionStorage({
  cookie: {
    name: "__session",
    maxAge: 3600, // 1 hour
    httpOnly: true,
    secure: false // OK for development
  }
});

// Development authentication
export async function loader({ request }: LoaderFunctionArgs) {
  const session = await sessionStorage.getSession(
    request.headers.get("Cookie")
  );
  
  const user = session.get("user");
  
  return json({ user });
}

export async function action({ request }: ActionFunctionArgs) {
  const session = await sessionStorage.getSession(
    request.headers.get("Cookie")
  );
  
  // Store user in memory session
  session.set("user", { id: 1, name: "Test User" });
  
  return redirect("/", {
    headers: {
      "Set-Cookie": await sessionStorage.commitSession(session)
    }
  });
}

Session Storage Types

All session storage implementations provide the same interface:

interface SessionStorage<Data = SessionData, FlashData = Data> {
  /**
   * Parses a Cookie header and returns a Session or null if cookie is invalid
   */
  getSession(cookieHeader?: string | null): Promise<Session<Data, FlashData>>;

  /**
   * Stores all data in the session and returns a Set-Cookie header
   */
  commitSession(
    session: Session<Data, FlashData>,
    options?: CookieSerializeOptions
  ): Promise<string>;

  /**
   * Destroys the session and returns a Set-Cookie header that expires the cookie
   */
  destroySession(
    session: Session<Data, FlashData>,
    options?: CookieSerializeOptions
  ): Promise<string>;
}

interface Session<Data = SessionData, FlashData = Data> {
  /** Unique session identifier */
  readonly id: string;
  /** Session data */
  readonly data: Partial<Data>;

  /** Check if the session has a value for the given key */
  has(key: keyof Data | keyof FlashData): boolean;

  /** Get a value from the session */
  get<Key extends keyof Data>(key: Key): Data[Key] | undefined;

  /** Set a value in the session */
  set<Key extends keyof Data>(key: Key, value: Data[Key]): void;

  /** Flash a value that will be available only on the next request */
  flash<Key extends keyof FlashData>(key: Key, value: FlashData[Key]): void;

  /** Remove a value from the session */
  unset(key: keyof Data | keyof FlashData): void;
}

Security Features

  • Cookie Signing: All cookies are signed using cookie-signature for tamper detection
  • Secret Rotation: Support for multiple secrets to enable secret rotation
  • Secure Defaults: HTTPOnly, Secure, and SameSite attributes configured appropriately
  • Expiration Handling: Automatic cleanup of expired sessions
  • Data Integrity: Signed cookies prevent client-side tampering

Storage Strategy Comparison

Storage TypeData LocationCapacityPerformancePersistence
CookieClient browser~4KBFastBrowser-dependent
MemoryServer RAMUnlimitedFastestProcess lifetime
FileServer filesystemUnlimitedGoodPersistent
CustomUser-definedVariesVariesUser-defined

Install with Tessl CLI

npx tessl i tessl/npm-remix-run--node

docs

cookie-session.md

global-polyfills.md

index.md

server-runtime.md

session-storage.md

stream-utilities.md

upload-handling.md

tile.json