Skip to main content

Add OAuth2 and OpenID Connect to your ExpressJS app

Adding OAuth2 to any application using the Ory Network is straight forward. This guide demonstrates how to write an app receiving OAuth2 and OpenID Connect tokens.

Prerequisites

  1. Install the Ory CLI

  2. Create an Ory Network project if you don't have one yet:

    ory create project --name "Ory Docs OAuth2 Integration Example"
    project_id="{set to the project ID from output}"

    # Use the email identity schema preset
    ory patch identity-config $project_id \
    --replace '/identity/default_schema_id="preset://email"' \
    --replace '/identity/schemas=[{"id":"preset://email","url":"base64://ewogICIkaWQiOiAiaHR0cHM6Ly9zY2hlbWFzLm9yeS5zaC9wcmVzZXRzL2tyYXRvcy9pZGVudGl0eS5lbWFpbC5zY2hlbWEuanNvbiIsCiAgIiRzY2hlbWEiOiAiaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjIiwKICAidGl0bGUiOiAiUGVyc29uIiwKICAidHlwZSI6ICJvYmplY3QiLAogICJwcm9wZXJ0aWVzIjogewogICAgInRyYWl0cyI6IHsKICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgImVtYWlsIjogewogICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICJmb3JtYXQiOiAiZW1haWwiLAogICAgICAgICAgInRpdGxlIjogIkUtTWFpbCIsCiAgICAgICAgICAib3J5LnNoL2tyYXRvcyI6IHsKICAgICAgICAgICAgImNyZWRlbnRpYWxzIjogewogICAgICAgICAgICAgICJwYXNzd29yZCI6IHsKICAgICAgICAgICAgICAgICJpZGVudGlmaWVyIjogdHJ1ZQogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgIndlYmF1dGhuIjogewogICAgICAgICAgICAgICAgImlkZW50aWZpZXIiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAidG90cCI6IHsKICAgICAgICAgICAgICAgICJhY2NvdW50X25hbWUiOiB0cnVlCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVjb3ZlcnkiOiB7CiAgICAgICAgICAgICAgInZpYSI6ICJlbWFpbCIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInZlcmlmaWNhdGlvbiI6IHsKICAgICAgICAgICAgICAidmlhIjogImVtYWlsIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgIm1heExlbmd0aCI6IDMyMAogICAgICAgIH0KICAgICAgfSwKICAgICAgInJlcXVpcmVkIjogWwogICAgICAgICJlbWFpbCIKICAgICAgXSwKICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogZmFsc2UKICAgIH0KICB9Cn0K"}]'
    export ORY_PROJECT_SLUG="{set to the project slug from output}"
  3. Create an OAuth2 client to be used by your app:

    note

    If you are not using our example code, replace http://localhost:3000/callback with the URL of your app's callback endpoint.

    ory create oauth2-client --project $project_id \
    --name "Ory Docs OAuth2 Integration Example Client" \
    --grant-type authorization_code,refresh_token,client_credentials \
    --response-type code \
    --scope openid --scope offline_access --scope email \
    --redirect-uri http://localhost:3000/callback
    export OAUTH_CLIENT_ID="{set to the client ID from output}"
    export OAUTH_CLIENT_SECRET="{set to the client secret from output}"

Add OAuth2 to ExpressJS

Adding OAuth2 to an ExpressJS app is straight forward. Create the ExpressJS application from scratch

mkdir example
cd example
npm init -y
npm install express-openid-connect express

and create a file server.js with the following content:

// Copyright © 2022 Ory Corp
// SPDX-License-Identifier: Apache-2.0

const { randomBytes } = require("crypto")
const express = require("express")
const { auth, requiresAuth } = require("express-openid-connect")
const app = express()

// The `auth` router attaches /login, /logout
// and /callback routes to the baseURL
app.use(
auth({
authRequired: false,
baseURL: "http://localhost:3000",
secret: process.env.ENCRYPTION_SECRET || randomBytes(64).toString("hex"),

clientID: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
issuerBaseURL: `https://${process.env.ORY_PROJECT_SLUG}.projects.oryapis.com`,

authorizationParams: {
response_type: "code",
scope: "openid email offline_access",
},
}),
)

// The / route will show the full oidc payload
app.get("/", requiresAuth(), (req, res) => {
req.oidc.fetchUserInfo().then((userInfo) => {
res.send(
`<html lang='en'><body><pre><code>${JSON.stringify(
{
accessToken: req.oidc.accessToken,
refreshToken: req.oidc.refreshToken,
idToken: req.oidc.idToken,
idTokenClaims: req.oidc.idTokenClaims,
userInfo,
},
null,
2,
)}</code></pre></body></html>`,
)
})
})

app.listen(3000, function () {
console.log("Listening on http://localhost:3000")
})

Finally, start the server

export ORY_PROJECT_SLUG="{set to the project slug from output}"
export OAUTH_CLIENT_ID="{set to the client ID from output}"
export OAUTH_CLIENT_SECRET="{set to the client secret from output}"

node server.js

and open http://localhost:3000 in your browser.