{"id":17666,"library":"grant-express","title":"Grant Express Middleware","description":"Grant Express is an Express.js middleware that acts as a handler for the Grant OAuth Proxy, simplifying authentication and authorization flows within Node.js applications. It integrates the robust Grant core library, which provides universal OAuth support for over 200 providers including Google, GitHub, Facebook, and many others. The current stable version for `grant-express` is 5.4.8. Grant is designed to abstract away the complexities of OAuth 1.0a, 2.0, and OpenID Connect, offering a unified configuration system and flexible integration with various HTTP frameworks and serverless environments. Its key differentiators include broad provider compatibility, a declarative configuration approach, and its ability to function as an embeddable OAuth client. The package facilitates managing OAuth callbacks, tokens, and session state efficiently, though users must provide their own session store. Release cadence is tied to the underlying Grant core library, which is actively maintained with updates for new providers, OAuth specification changes, and security patches.","status":"active","version":"5.4.8","language":"javascript","source_language":"en","source_url":"https://github.com/simov/grant","tags":["javascript","oauth","oauth2","openid","openid-connect","authentication","authorization","proxy","middleware","typescript"],"install":[{"cmd":"npm install grant-express","lang":"bash","label":"npm"},{"cmd":"yarn add grant-express","lang":"bash","label":"yarn"},{"cmd":"pnpm add grant-express","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Runtime peer dependency for the middleware framework.","package":"express","optional":false},{"reason":"Required by Grant for persisting state between HTTP redirects during the OAuth flow.","package":"express-session","optional":false}],"imports":[{"note":"For ES Modules, `grant-express` exports the middleware factory function as its default export. Call it with your configuration object to get the Express middleware: `app.use(Grant(config))`.","wrong":"import { Grant } from 'grant-express'","symbol":"Grant","correct":"import Grant from 'grant-express'"},{"note":"For CommonJS, `require('grant-express')` returns the middleware factory function. Call it with your configuration object to get the Express middleware: `app.use(Grant(config))`.","wrong":"const { Grant } = require('grant-express')","symbol":"Grant","correct":"const Grant = require('grant-express')"},{"note":"The TypeScript interface for the configuration object, `GrantConfig`, is provided by the underlying `grant` package, as `grant-express` is a handler for it.","symbol":"GrantConfig","correct":"import type { GrantConfig } from 'grant'"}],"quickstart":{"code":"import express from 'express';\nimport session from 'express-session';\nimport Grant from 'grant-express';\nimport dotenv from 'dotenv';\n\ndotenv.config(); // Load environment variables\n\nconst app = express();\nconst port = process.env.PORT || 3000;\n\n// IMPORTANT: Grant requires a session middleware\napp.use(session({\n  secret: process.env.SESSION_SECRET ?? 'your-very-secret-key-that-should-be-random',\n  resave: false,\n  saveUninitialized: false,\n  cookie: { secure: process.env.NODE_ENV === 'production' }\n}));\n\n// Grant configuration for GitHub OAuth\nconst grantConfig = {\n  defaults: {\n    origin: `http://localhost:${port}`,\n    transport: 'session',\n    state: true\n  },\n  github: {\n    key: process.env.GITHUB_CLIENT_ID ?? '',\n    secret: process.env.GITHUB_CLIENT_SECRET ?? '',\n    scope: ['user:email', 'read:user'],\n    callback: '/callback'\n  }\n};\n\n// Mount the Grant middleware\napp.use(Grant(grantConfig));\n\n// Route to initiate GitHub OAuth\napp.get('/login/github', (req, res) => {\n  // Redirects to /connect/github which Grant handles\n  res.redirect('/connect/github');\n});\n\n// Callback route to handle OAuth response\napp.get('/callback', (req, res) => {\n  if (req.query.error) {\n    return res.status(400).send(`OAuth Error: ${req.query.error_description || req.query.error}`);\n  }\n  // Grant places the OAuth response data in req.session.grant.response\n  const { access_token, profile } = (req.session as any)?.grant?.response?.github?.raw || {};\n  if (access_token) {\n    res.send(`\n      <h1>Authentication Successful!</h1>\n      <p>Access Token: ${access_token}</p>\n      <p>User Profile (partial): ${profile ? JSON.stringify(profile.data, null, 2) : 'N/A'}</p>\n      <p><a href=\"/\">Home</a></p>\n    `);\n  } else {\n    res.status(500).send('Authentication failed: No access token received.');\n  }\n});\n\n// Basic home route\napp.get('/', (req, res) => {\n  res.send(`\n    <h1>Welcome to Grant Express Example</h1>\n    <p><a href=\"/login/github\">Login with GitHub</a></p>\n  `);\n});\n\napp.listen(port, () => {\n  console.log(`Server running at http://localhost:${port}`);\n  console.log('Ensure GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, and SESSION_SECRET environment variables are set.');\n});","lang":"typescript","description":"Demonstrates setting up Grant Express middleware with a basic Express server and GitHub OAuth for user authentication, including session management and environment variable usage for credentials."},"warnings":[{"fix":"Review your Express application for v5 breaking changes. Ensure `grant` (the core library) is updated to its latest version, which typically includes compatibility fixes for newer Express releases. Test thoroughly after upgrading `express`.","message":"Express v5 introduced several breaking changes. While `grant-express` has a peer dependency on `express` `>=3.0.0`, ensuring full compatibility with the latest `express` v5 might require explicit updates to the `grant` core library or specific configuration adjustments. Consult the `express` migration guide and the `grant` documentation for any known incompatibilities.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Install and configure `express-session` (or a compatible session store) and ensure `app.use(session(...))` is called *before* `app.use(Grant(...))` in your Express application's middleware chain.","message":"Grant requires a session middleware (e.g., `express-session`) to persist necessary state during the OAuth redirect flow. If not configured or placed correctly before `Grant` middleware, it will lead to runtime errors or failed authentication.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Always use environment variables, a secrets management service, or a secure configuration file to load sensitive credentials. Tools like `dotenv` can help manage environment variables in development.","message":"OAuth client IDs and secrets (e.g., `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`) should never be hardcoded directly into your application code. This is a severe security risk.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Carefully verify that the `origin` and `prefix` in your Grant configuration, along with the specific provider's `callback` path, exactly match what you have configured in the OAuth provider's developer settings.","message":"The OAuth `redirect_uri` (callback URL) must precisely match the URL registered with the OAuth provider (e.g., GitHub). Mismatches, including differences in `http` vs `https`, port numbers, or path segments, will cause `redirect_uri_mismatch` errors and prevent authentication.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Monitor the `grant` (core) repository for updates and breaking changes, as `grant-express` effectively wraps its functionality. If new Express versions or critical Node.js environment changes cause issues, direct contribution or seeking updates to `grant-express` itself may be necessary.","message":"The `grant-express` package itself was last published five years ago, while the core `grant` project (which it relies on) appears to be more actively maintained. This could mean direct `grant-express` specific updates might be delayed, though core `grant` updates should still apply.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure `express-session` (or an equivalent session management middleware) is installed and configured using `app.use(session({ ... }))` *before* mounting `grant-express` with `app.use(Grant(config))`.","cause":"The `grant-express` middleware was initialized and used without a preceding session middleware (like `express-session`). Grant relies on sessions to manage state across OAuth redirects.","error":"Error: Grant: session store is required"},{"fix":"Double-check your Grant configuration (`origin`, `prefix`, and provider `callback`) and compare it precisely with the Authorized Redirect URIs listed in your OAuth provider's application settings. Pay attention to `http` vs `https`, domain, port, and path segments.","cause":"The callback URL configured for your application on the OAuth provider's website does not exactly match the `redirect_uri` that Grant generates based on your `origin`, `prefix`, and provider configuration.","error":"OAuth error: redirect_uri_mismatch"},{"fix":"For ES Modules, use `import Grant from 'grant-express';`. For CommonJS, use `const Grant = require('grant-express');`. Ensure you are calling the imported `Grant` function to create the middleware, e.g., `app.use(Grant(config))`.","cause":"The `grant-express` module was imported or required incorrectly, or you are attempting to use it as a named export when it is a default export (or vice-versa for CommonJS).","error":"TypeError: Grant is not a function"},{"fix":"Verify that `app.use(Grant(config))` is called correctly in your Express setup. Confirm that the `prefix` in your `grantConfig` matches the base path from which you expect Grant to handle routes (e.g., if `prefix: '/auth'`, then `/auth/github` would initiate the flow).","cause":"The `grant-express` middleware is either not mounted in your Express application, or its configured `prefix` does not match the URL paths being accessed, causing Express to not find a handler.","error":"Cannot GET /connect/provider or Cannot POST /callback"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}