Protect a Page with Login in NodeJS / ExpressJS
In this guide, we set up a new ExpressJS application and protect its home page with a login page using Ory. It will also add features such as profile settings, registration, and more. You can use this guide with both Ory Cloud and by self-hosting Ory software.
This guide is for you if you:
- have NodeJS installed;
- want to use ExpressJS to build an application;
- want to show your app only if the user is logged in.
Before we start, let's take a look at what user flow you will implement with this guide.
Create ExpressJS App​
First we create a new ExpressJS 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?​
The Ory CLI includes useful functionality to manage your Ory Cloud Project. But that is not why we require it in this guide!
Ory's philosophy is to make hard things easy for you. For this reason, Ory has deployed measures against all OWASP Top 10 and implements the OWASP Authentication Cheat Sheet along other mechanisms.
Therefore, Ory manages Anti-CSRF Cookies as well as Ory Session Cookies for you. That however requries that Ory and your application run on the same domain!
If your application runs on http://localhost:3000
then Ory needs to be
available on the hostname localhost
as well (e.g. http://localhost:3001
).
That is why we need the Ory CLI, because it has a proxy included which mirrors
Ory's API endpoints on the domain of your application.
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.V0alpha2Api(
new sdk.Configuration({
baseUrl: '/.ory'
})
)
/* GET home page. */
router.get('/', function (req, res, next) {
ory
.toSession(undefined, 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 ExpressJS App​
Great, that's it! Let's run your application! Start the ExpressJS server
npm run start
and set up your environment variables to connect with Ory's APIs
- Mac OS
- Linux
- Windows CMD
- Windows Powershell
- Self-Hosted Ory Kratos
# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples!
export ORY_SDK_URL=https://playground.projects.oryapis.com
# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples!
export ORY_SDK_URL=https://playground.projects.oryapis.com
# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples!
set ORY_SDK_URL=https://playground.projects.oryapis.com
# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples!
$Env:ORY_SDK_URL = "https://playground.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
Then 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​
Going to production with your app is possible in many ways. Whether you deploy
it on Kubernetes, AWS, a VM, or a RaspberryPi is up to you. To get your app
working with Ory it is important that Ory and your app are available under the
same common domain (e.g. https://ory.example.com
and
https://www.example.com
).
The easiest way to connect Ory to your domain is to connect Ory to a subdomain of yours. You can do this easily by adding a Custom Domain to your Cloud project!
With the custom domain set up, you do not need the Ory Proxy anymore and will use the configured custom domain in your SDK calls:
var sdk = require('@ory/client')
var ory = new sdk.V0alpha2Api(
new sdk.Configuration({
baseUrl: 'https://ory.example.org',
baseOptions: {
// Ensures that cookies are included in CORS requests:
withCredentials: true
}
})
)