JSPM

@remix-run/session-middleware

0.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 158
  • Score
    100M100P100Q67328F
  • License MIT

Middleware for managing sessions with cookie-based storage

Package Exports

  • @remix-run/session-middleware
  • @remix-run/session-middleware/package.json

Readme

session-middleware

Middleware for managing sessions with @remix-run/fetch-router via securely signed cookies.

Installation

npm install @remix-run/session-middleware

Usage

import { createRouter } from '@remix-run/fetch-router'
import { createCookie } from '@remix-run/cookie'
import { createCookieStorage } from '@remix-run/session/cookie-storage'
import { session } from '@remix-run/session-middleware'

let sessionCookie = createCookie('__session', {
  secrets: ['s3cr3t'], // session cookies must be signed!
  httpOnly: true,
  secure: true,
  sameSite: 'lax',
})

let sessionStorage = createCookieStorage()

let router = createRouter({
  middleware: [session(sessionCookie, sessionStorage)],
})

router.get('/', (context) => {
  context.session.set('count', Number(context.session.get('count') ?? 0) + 1)
  return new Response(`Count: ${context.session.get('count')}`)
})

The middleware:

  • Reads the session from the cookie on incoming requests
  • Makes it available as context.session
  • Automatically saves session changes and sets the cookie on responses

Note: The session cookie must be signed for security. This prevents tampering with the session data on the client.

Login/Logout Flow

A basic login/logout flow could look like this:

import * as res from '@remix-run/fetch-router/response-helpers'
import { html } from '@remix-run/html-template'

router.get('/login', ({ session }) => {
  let error = session.get('error')
  return res.html(
    html` <div>
      <h1>Login</h1>
      ${typeof error === 'string' ? <div class="error">${error}</div> : null}
      <form method="POST" action="/login">
        <input type="text" name="username" placeholder="Username" />
        <input type="password" name="password" placeholder="Password" />
        <button type="submit">Login</button>
      </form>
    </div>`,
  )
})

router.post('/login', ({ session, formData }) => {
  let username = formData.get('username')
  let password = formData.get('password')

  let user = authenticateUser(username, password)
  if (!user) {
    session.flash('error', 'Invalid username or password')
    return res.redirect('/login')
  }

  session.set('userId', user.id)
  session.regenerateId()

  return res.redirect('/dashboard')
})

router.post('/logout', ({ session }) => {
  session.destroy()
  return res.redirect('/')
})
  • fetch-router - Router for the web Fetch API
  • session - Session management and storage
  • cookie - Cookie parsing and serialization

License

See LICENSE