@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
- Yarn
- pnpm
npm install @auth/express
yarn add @auth/express
pnpm add @auth/express
Usageβ
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
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:
// 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:
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:
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 theauthorize()
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β
- https://authjs.dev/guides/basics/refresh-token-rotation#database-strategy
- https://www.rfc-editor.org/rfc/rfc6749#section-5.1
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