Skip to main content

@auth/express

warning

@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()

// Make sure to use these body parsers so Auth.js can receive data from the client
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

// If app is served through a proxy, trust the proxy to allow HTTPS protocol to be detected
app.use('trust proxy')

app.use(
"/api/auth/*",
ExpressAuth({
providers: [
GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
})
)

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]/api/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 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)

Account​

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

Extends​

  • Partial< OpenIDTokenEndpointResponse >

Properties​

provider​

provider: string

Provider's id for this account. Eg.: "google"

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

type​

type: ProviderType

Provider's type for this account

expires_at​

expires_at?: number

Calculated value based on [OAuth2TokenEndpointResponse.expires_in]([object Object]).

It is the absolute timestamp (in seconds) when the [OAuth2TokenEndpointResponse.access_token]([object Object]) expires.

This value can be used for implementing token rotation together with [OAuth2TokenEndpointResponse.refresh_token]([object Object]).

See​

userId​

userId?: string

id of the user this account belongs to

See​

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


Profile​

The user info returned from your OAuth provider.

See​

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


Session​

Returned by useSession, getSession, returned by the session callback and also the shape received as a prop on the SessionProvider React Context

useSession | getSession | SessionProvider | session callback

Extends​

  • DefaultSession

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.

signIn callback | session callback | jwt callback | profile OAuth provider callback