Skip to content
Migrating from NextAuth.js v4? Read our migration guide.
API reference
@auth/express

@auth/express

⚠️

@auth/express is currently experimental. The API will change in the future.

Express Auth is the official Express integration for Auth.js. It provides a simple way to add authentication to your Express app in a few lines of code.

Installation

npm install @auth/express

Usage

src/routes/auth.route.ts
import { ExpressAuth } from "@auth/express"
import GitHub from "@auth/express/providers/github"
import express from "express"
 
const app = express()
 
// If app is served through a proxy, trust the proxy to allow HTTPS protocol to be detected
// https://expressjs.com/en/guide/behind-proxies.html
app.set('trust proxy', true)
app.use("/auth/*", ExpressAuth({ providers: [ GitHub ] }))

Don’t forget to set the AUTH_SECRET environment variable. This should be a minimum of 32 characters, random string. On UNIX systems you can use openssl rand -hex 32 or check out https://generate-secret.vercel.app/32.

You will also need to load the environment variables into your runtime environment. For example in Node.js with a package like dotenv or Deno.env in Deno.

Provider Configuration

The callback URL used by the providers must be set to the following, unless you mount the ExpressAuth handler on a different path:

[origin]/auth/callback/[provider]

Signing in and signing out

Once your application is mounted you can sign in or out by making requests to the following REST API endpoints from your client-side code. NB: Make sure to include the csrfToken in the request body for all sign-in and sign-out requests.

Managing the session

If you are using Express with a template engine (e.g EJS, Pug), you can make the session data available to all routes via middleware as follows

app.ts
import { getSession } from "@auth/express"
 
export function authSession(req: Request, res: Response, next: NextFunction) {
  res.locals.session = await getSession(req)
  next()
}
 
app.use(authSession)
 
// Now in your route
app.get("/", (req, res) => {
  const { session } = res.locals
  res.render("index", { user: session?.user })
})

Authorization

You can protect routes by checking for the presence of a session and then redirect to a login page if the session is not present. This can either be done per route, or for a group of routes using a middleware such as the following:

export async function authenticatedUser(
  req: Request,
  res: Response,
  next: NextFunction
) {
  const session = res.locals.session ?? (await getSession(req, authConfig))
  if (!session?.user) {
    res.redirect("/login")
  } else {
    next()
  }
}

Per Route

To protect a single route, simply add the middleware to the route as follows:

app.ts
// This route is protected
app.get("/profile", authenticatedUser, (req, res) => {
  const { session } = res.locals
  res.render("profile", { user: session?.user })
})
 
// This route is not protected
app.get("/", (req, res) => {
  res.render("index")
})
 
app.use("/", root)

Per Group of Routes

To protect a group of routes, define a router and add the middleware to the router as follows:

routes/protected.route.ts
import { Router } from "express"
 
const router = Router()
 
router.use(authenticatedUser) // All routes defined after this will be protected
 
router.get("/", (req, res) => {
  res.render("protected")
})
 
export default router

Then we mount the router as follows:

app.ts
import protected from "./routes/protected.route"
 
app.use("/protected", protected)

Notes on ESM

@auth/express is ESM only. This means your package.json must contain "type": "module" and tsconfig.json should contain "module": "NodeNext" or ESNext. File imports must use the .js extension, e.g. import { MyRouter } from "./my-router.js".

Your dev server should either be run with tsx with tsx index.ts (fast startup, with no type checking), or ts-node with ‘node —loader ts-node/esm index.ts’ (slower startup, but has type checking).

While it is NOT recommended, if you wish to use @auth/express within a CommonJS project without migrating and making the above changes, you can run the dev server with tsx and may be able to compile with pkgroll. Add ‘“name”: ”./dist/index.js”’ or ‘“name”: ”./dist/index.mjs”’ to your package.json and run ‘pkgroll’ to compile with both ESM and CommonJS support. For new projects it is recommended to just use ESM.

AuthError

Base error class for all Auth.js errors. It’s optimized to be printed in the server logs in a nicely formatted way via the logger.error option.

Extends

Constructors

new AuthError(message, errorOptions)

new AuthError(message?, errorOptions?): AuthError
Parameters
ParameterType
message?string | ErrorOptions
errorOptions?ErrorOptions
Returns

AuthError

Overrides

Error.constructor

Properties

cause?

optional cause: Record<string, unknown> & {
  err: Error;
};
Type declaration
err?
optional err: Error;
Overrides

Error.cause

message

message: string;
Inherited from

Error.message

name

name: string;
Inherited from

Error.name

stack?

optional stack: string;
Inherited from

Error.stack

type

type: ErrorType;

The error type. Used to identify the error in the logs.

prepareStackTrace()?

static optional prepareStackTrace: (err, stackTraces) => any;

Optional override for formatting stack traces

See

https://v8.dev/docs/stack-trace-api#customizing-stack-traces

Parameters
ParameterType
errError
stackTracesCallSite[]
Returns

any

Inherited from

Error.prepareStackTrace

stackTraceLimit

static stackTraceLimit: number;
Inherited from

Error.stackTraceLimit

Methods

captureStackTrace()

static captureStackTrace(targetObject, constructorOpt?): void

Create .stack property on a target object

Parameters
ParameterType
targetObjectobject
constructorOpt?Function
Returns

void

Inherited from

Error.captureStackTrace


CredentialsSignin

Can be thrown from the authorize callback of the Credentials provider. When an error occurs during the authorize callback, two things can happen:

  1. The user is redirected to the signin page, with error=CredentialsSignin&code=credentials in the URL. code is configurable.
  2. If you throw this error in a framework that handles form actions server-side, this error is thrown, instead of redirecting the user, so you’ll need to handle.

Extends

Constructors

new CredentialsSignin(message, errorOptions)

new CredentialsSignin(message?, errorOptions?): CredentialsSignin
Parameters
ParameterType
message?string | ErrorOptions
errorOptions?ErrorOptions
Returns

CredentialsSignin

Inherited from

SignInError.constructor

Properties

cause?

optional cause: Record<string, unknown> & {
  err: Error;
};
Type declaration
err?
optional err: Error;
Inherited from

SignInError.cause

code

code: string;

The error code that is set in the code query parameter of the redirect URL.

⚠ NOTE: This property is going to be included in the URL, so make sure it does not hint at sensitive errors.

The full error is always logged on the server, if you need to debug.

Generally, we don’t recommend hinting specifically if the user had either a wrong username or password specifically, try rather something like “Invalid credentials”.

message

message: string;
Inherited from

SignInError.message

name

name: string;
Inherited from

SignInError.name

stack?

optional stack: string;
Inherited from

SignInError.stack

type

type: ErrorType;

The error type. Used to identify the error in the logs.

Inherited from

SignInError.type

kind

static kind: string;
Inherited from

SignInError.kind

prepareStackTrace()?

static optional prepareStackTrace: (err, stackTraces) => any;

Optional override for formatting stack traces

See

https://v8.dev/docs/stack-trace-api#customizing-stack-traces

Parameters
ParameterType
errError
stackTracesCallSite[]
Returns

any

Inherited from

SignInError.prepareStackTrace

stackTraceLimit

static stackTraceLimit: number;
Inherited from

SignInError.stackTraceLimit

type

static type: string;

Methods

captureStackTrace()

static captureStackTrace(targetObject, constructorOpt?): void

Create .stack property on a target object

Parameters
ParameterType
targetObjectobject
constructorOpt?Function
Returns

void

Inherited from

SignInError.captureStackTrace


Account

Usually contains information about the provider being used and also extends TokenSet, which is different tokens returned by OAuth Providers.

Extends

Properties

access_token?

optional readonly access_token: string;
Inherited from

Partial.access_token

authorization_details?

optional readonly authorization_details: AuthorizationDetails[];
Inherited from

Partial.authorization_details

expires_at?

optional expires_at: number;

Calculated value based on TokenEndpointResponse.expires_in.

It is the absolute timestamp (in seconds) when the TokenEndpointResponse.access_token expires.

This value can be used for implementing token rotation together with TokenEndpointResponse.refresh_token.

See

expires_in?

optional readonly expires_in: number;
Inherited from

Partial.expires_in

id_token?

optional readonly id_token: string;
Inherited from

Partial.id_token

provider

provider: string;

Provider’s id for this account. E.g. “google”. See the full list at https://authjs.dev/reference/core/providers

providerAccountId

providerAccountId: string;

This value depends on the type of the provider being used to create the account.

  • oauth/oidc: The OAuth account’s id, returned from the profile() callback.
  • email: The user’s email address.
  • credentials: id returned from the authorize() callback

refresh_token?

optional readonly refresh_token: string;
Inherited from

Partial.refresh_token

scope?

optional readonly scope: string;
Inherited from

Partial.scope

token_type?

optional readonly token_type: Lowercase<string>;

NOTE: because the value is case insensitive it is always returned lowercased

Inherited from

Partial.token_type

type

type: ProviderType;

Provider’s type for this account

userId?

optional userId: string;

id of the user this account belongs to

See

https://authjs.dev/reference/core/adapters#adapteruser


DefaultSession

Extended by

Properties

expires

expires: string;

user?

optional user: User;

Profile

The user info returned from your OAuth provider.

See

https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims

Indexable

[claim: string]: unknown

Properties

address?

optional address: null | {
  country: null | string;
  formatted: null | string;
  locality: null | string;
  postal_code: null | string;
  region: null | string;
  street_address: null | string;
};

birthdate?

optional birthdate: null | string;

email?

optional email: null | string;

email_verified?

optional email_verified: null | boolean;

family_name?

optional family_name: null | string;

gender?

optional gender: null | string;

given_name?

optional given_name: null | string;

id?

optional id: null | string;

locale?

optional locale: null | string;

middle_name?

optional middle_name: null | string;

name?

optional name: null | string;

nickname?

optional nickname: null | string;

phone_number?

optional phone_number: null | string;

picture?

optional picture: any;

preferred_username?

optional preferred_username: null | string;

profile?

optional profile: null | string;

sub?

optional sub: null | string;

updated_at?

optional updated_at: null | string | number | Date;

website?

optional website: null | string;

zoneinfo?

optional zoneinfo: null | string;

Session

The active session of the logged in user.

Extends

Properties

expires

expires: string;
Inherited from

DefaultSession.expires

user?

optional user: User;
Inherited from

DefaultSession.user


User

The shape of the returned object in the OAuth providers’ profile callback, available in the jwt and session callbacks, or the second parameter of the session callback, when using a database.

Extended by

Properties

email?

optional email: null | string;

id?

optional id: string;

image?

optional image: null | string;

name?

optional name: null | string;

ExpressAuthConfig

type ExpressAuthConfig: Omit<AuthConfig, "raw">;

GetSessionResult

type GetSessionResult: Promise<Session | null>;

customFetch

const customFetch: unique symbol;

This advanced option allows you to override the default fetch function used by the provider to make requests to the provider’s OAuth endpoints.

It can be used to support corporate proxies, custom fetch libraries, cache discovery endpoints, add mocks for testing, logging, set custom headers/params for non-spec compliant providers, etc.

Example

import { Auth, customFetch } from "@auth/core"
import GitHub from "@auth/core/providers/github"
 
const dispatcher = new ProxyAgent("my.proxy.server")
function proxy(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {
  return undici(args[0], { ...(args[1] ?? {}), dispatcher })
}
 
const response = await Auth(request, {
  providers: [GitHub({ [customFetch]: proxy })]
})

See


ExpressAuth()

ExpressAuth(config): (req, res, next) => Promise<void>

Parameters

ParameterType
configExpressAuthConfig

Returns

Function

Parameters

ParameterType
reqRequest<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
resResponse<any, Record<string, any>>
nextNextFunction

Returns

Promise<void>


getSession()

getSession(req, config): GetSessionResult

Parameters

ParameterType
reqRequest<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
configExpressAuthConfig

Returns

GetSessionResult

Auth.js © Balázs Orbán and Team - 2024