Integrate authentication into Node.js / Express.js
This guide shows how to create a simple Express.js application and secure it with authentication powered by Ory. You can use this guide with both Ory Network and self-hosted Ory software.
This guide is perfect for you if:
- You have Express.js installed.
- You want to build an app using Express.js.
- You want to give access to your application to signed-in users only.
Before you start, watch this video to see the user flow you're going to implement:
You can find the code of the sample application here.
Create Express.js app
First we create a new Express.js project:
mkdir your-project
cd your-project
npx express-generator
npm i
Install Ory SDK
To interact with Ory's APIs we install the Ory SDK:
npm i --save @ory/client
Install Ory CLI
The last step is setting up the Ory CLI.
npm i --save @ory/cli
Why do I Need the Ory CLI?
Ory CLI provides a convenient way to configure and manage projects. Additionally, the CLI contains Ory Proxy - a reverse proxy that rewrites cookies to match the domain your application is currently on.
Ory Proxy is a reverse proxy deployed in front of your application. The Proxy mirrors Ory endpoints on the same domain as the application you're running and rewrites cookies to match the domain your application is currently on.
As a result, the origin of the cookies is set correctly to the domain you run the app on instead of
<your-project-slug>.projects.oryapis.com
This behavior is necessary to avoid issues with the browser CORS policy.
By using the Proxy, you can easily connect the application you're developing locally to Ory Network and consume the APIs without additional configuration or the self-hosting any Ory services.
To learn more about the Ory Proxy, read the dedicated section of the Ory CLI documentation.
Add NPM run script
Now that the Ory CLI is installed, let's add it as a npm run
script to our project:
{
"name": "protect-page-login",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"proxy": "ory proxy --no-jwt --port 4000 http://localhost:3000/"
},
"dependencies": {
This requires the express app (npm run start
) to run on port 3000. The browser / user uses however the port 4000
(http://localhost:4000) to access the app.
Require login to access the home page
Next we add a session check to the default home page of the example application. The highlighted code is what we added to check whether the user is signed in, and redirect them to the login page if not:
var express = require("express")
var router = express.Router()
var sdk = require("@ory/client")
var ory = new sdk.FrontendApi(
new sdk.Configuration({
basePath:
process.env.ORY_SDK_URL || "https://playground.projects.oryapis.com",
}),
)
/* GET home page. */
router.get("/", function (req, res, next) {
ory
.toSession({ cookie: req.header("cookie") })
.then(({ data: session }) => {
res.render("index", {
title: "Express",
// Our identity is stored in the session along with other useful information.
identity: session.identity,
})
})
.catch(() => {
// If logged out, send to login page
res.redirect("/.ory/ui/login")
})
})
module.exports = router
Run your Express.js app
Great, that's it. Let's run your application. Start the Express.js server
npm run start
and set up your environment variables to connect with Ory's APIs
- macOS
- Linux
- Windows CMD
- Windows Powershell
- Self-Hosted Ory Kratos
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
export ORY_SDK_URL=https://$PROJECT_SLUG.projects.oryapis.com
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
export ORY_SDK_URL=https://$PROJECT_SLUG.projects.oryapis.com
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
set ORY_SDK_URL=https://$PROJECT_SLUG.projects.oryapis.com
# This is a public Ory Network Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up to Ory Network at
#
# https://console.ory.sh/registration
#
# and create a free Ory Network Project to see your own configuration embedded in code samples.
$Env:ORY_SDK_URL = "https://$PROJECT_SLUG.projects.oryapis.com"
Clone and run Ory Kratos locally
git clone --depth 1 --branch master https://github.com/ory/kratos.git
cd kratos
git checkout master
git pull -ff
docker-compose -f quickstart.yml -f contrib/quickstart/kratos/cloud/quickstart.yml up --build --force-recreate -d
and set the environment variable to the exposed port:
export ORY_SDK_URL=http://localhost:4433
Next open a new terminal window and start the Ory Proxy:
npm run proxy
To access the Express.js app through the ORY proxy open http://localhost:4000 in your browser. You are presented with Ory's Sign In page. Let's click on sign up and create your first user.
Go to production
You can use many different approaches to go to production with your application. You can deploy it on Kubernetes, AWS, a VM, a
RaspberryPi - the choice is yours! To connect the application to your Ory project, the app and Ory APIs must be available under
the same common domain, for example https://ory.example.com
and https://www.example.com
.
You can easily connect Ory to your subdomain. To do that, add a Custom Domain to your Ory Network project.
With the custom domain set up, you don't need to use Ory Proxy or Ory Tunnel to interact with Ory APIs. Instead, use the configured custom domain in your SDK calls:
var sdk = require("@ory/client")
var ory = new sdk.FrontendApi(
new sdk.Configuration({
basePath: "https://ory.example.org",
baseOptions: {
// Ensures that cookies are included in CORS requests:
withCredentials: true,
},
}),
)