View on Github


Gravatar for
By Josh Cunningham

This tutorial demonstrates how to add user login, logout, and profile to a Node.js Express application. We recommend that you log in to follow this quickstart with examples configured for your account.

I want to explore a sample app

2 minutes

Get a sample configured with your account settings or check it out on Github.

View on Github
System requirements: NodeJS 4.3 or higher | Express 4.16

New to Auth? Learn How Auth0 works, how it integrates with Regular Web Applications and which protocol it uses.

Configure Auth0

Get Your Application Keys

When you signed up for Auth0, a new application was created for you, or you could have created a new one. You will need some details about that application to communicate with Auth0. You can get these details from the Application Settings section in the Auth0 dashboard.

App Dashboard

You need the following information:

  • Domain
  • Client ID
  • Client Secret

If you download the sample from the top of this page, these details are filled out for you.

Configure Callback URLs

A callback URL is a URL in your application where Auth0 redirects the user after they have authenticated. The callback URL for your app must be added to the Allowed Callback URLs field in your Application Settings. If this field is not set, users will be unable to log in to the application and will get an error.

If you are following along with the sample project you downloaded from the top of this page, the callback URL you need to add to the Allowed Callback URLs field is http://localhost:3000/callback.

Configure Logout URLs

A logout URL is a URL in your application that Auth0 can return to after the user has been logged out of the authorization server. This is specified in the returnTo query parameter. The logout URL for your app must be added to the Allowed Logout URLs field in your Application Settings. If this field is not set, users will be unable to log out from the application and will get an error.

If you are following along with the sample project you downloaded from the top of this page, the logout URL you need to add to the Allowed Logout URLs field is http://localhost:3000.

Configure Node.js to use Auth0

Create the .env file

Create the .env file in the root of your app and add your Auth0 variables and values to it.

# .env

Do not put the .env file into source control. Otherwise, your history will contain references to your client secret.

If you are using git, create a .gitignore file (or edit your existing one, if you have one already) and add .env to it. The .gitignore file tells source control to ignore the files (or file patterns) you list. Be careful to add .env to your .gitignore file and commit that change before you add your .env.

# .gitignore

Install the dependencies

To get started, install the following dependencies.

  • passport - an authentication middleware for Node.js
  • passport-auth0 - an Auth0 authentication strategy for Passport
  • express-session - a middleware to manage sessions
  • dotenv - a module to load environment variables from a .env file
# installation with npm
npm install passport passport-auth0 express-session dotenv --save

Configure express-session

In app.js, include the express-session module and configure it. The secret parameter is a secret string that is used to sign the session ID cookie. Please use a custom value.

// app.js

var session = require('express-session');

// config express-session
var sess = {
  cookie: {},
  resave: false,
  saveUninitialized: true

if (app.get('env') === 'production') {
  // Use secure cookies in production (requires SSL/TLS) = true;

  // Uncomment the line below if your application is behind a proxy (like on Heroku)
  // or if you're encountering the error message:
  // "Unable to verify authorization request state"
  // app.set('trust proxy', 1);


Configure Passport with the application settings

In app.js, include the passport and passport-auth0 modules, and configure Passport to use a new instance of Auth0Strategy with your Auth0 application settings. Use passport.initialize() and passport.session() to initialize Passport with persistent login sessions.

// app.js

// Load environment variables from .env
var dotenv = require('dotenv');

// Load Passport
var passport = require('passport');
var Auth0Strategy = require('passport-auth0');

// Configure Passport to use Auth0
var strategy = new Auth0Strategy(
    domain: process.env.AUTH0_DOMAIN,
    clientID: process.env.AUTH0_CLIENT_ID,
    clientSecret: process.env.AUTH0_CLIENT_SECRET,
      process.env.AUTH0_CALLBACK_URL || 'http://localhost:3000/callback'
  function (accessToken, refreshToken, extraParams, profile, done) {
    // accessToken is the token to call Auth0 API (not needed in the most cases)
    // extraParams.id_token has the JSON Web Token
    // profile has all the information from the user
    return done(null, profile);



Please make sure these last two commands are in your code after the application of the express middleware (app.use(session(sess)).

Storing and retrieving user data from the session

In a typical web application, the credentials used to authenticate a user are only transmitted during the login request. If authentication succeeds, a session is established and maintained via a cookie set in the user's browser. Each subsequent request does not contain credentials, but rather the unique cookie that identifies the session.

To support login sessions, Passport serializes and deserializes user instances to and from the session. Optionally, you may want to serialize only a subset to reduce the footprint, i.e.,

// app.js

// You can use this section to keep a smaller payload
passport.serializeUser(function (user, done) {
  done(null, user);

passport.deserializeUser(function (user, done) {
  done(null, user);

Implement login, user profile and logout

In this example, the following routes are implemented:

  • /login triggers the authentication by calling Passport's authenticate method. The user is then redirected to the tenant login page hosted by Auth0.
  • /callback is the route the user is returned to by Auth0 after authenticating. It redirects the user to the profile page (/user).
  • /user displays the user's profile.
  • /logout logs the user out of Auth0.

We will use the following routers:

  • routes/auth.js, to handle authentication
  • routes/index.js, to serve the home page
  • routes/users.js, to serve the user profile

Adding the authentication router

Start by creating a new router routes/auth.js to handle authentication.

In the authentication step, make sure to pass the scope parameter with values openid email profile to access email and the other attributes stored in the user profile. This is needed to display the user's information on the profile page.

// routes/auth.js

var express = require('express');
var router = express.Router();
var passport = require('passport');
var dotenv = require('dotenv');
var util = require('util');
var url = require('url');
var querystring = require('querystring');


// Perform the login, after login Auth0 will redirect to callback
router.get('/login', passport.authenticate('auth0', {
  scope: 'openid email profile'
}), function (req, res) {

// Perform the final stage of authentication and redirect to previously requested URL or '/user'
router.get('/callback', function (req, res, next) {
  passport.authenticate('auth0', function (err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }
    req.logIn(user, function (err) {
      if (err) { return next(err); }
      const returnTo = req.session.returnTo;
      delete req.session.returnTo;
      res.redirect(returnTo || '/user');
  })(req, res, next);

// Perform session logout and redirect to homepage
router.get('/logout', (req, res) => {

  var returnTo = req.protocol + '://' + req.hostname;
  var port = req.connection.localPort;
  if (port !== undefined && port !== 80 && port !== 443) {
    returnTo += ':' + port;
  var logoutURL = new url.URL(
    util.format('https://%s/v2/logout', process.env.AUTH0_DOMAIN)
  var searchString = querystring.stringify({
    client_id: process.env.AUTH0_CLIENT_ID,
    returnTo: returnTo
  }); = searchString;


module.exports = router;

This tutorial implements logout by closing the local user session and the user's Auth0 session as well. For other implementations, please refer to the logout documentation.

Middleware to protect routes

Create a secured middleware to protect routes and ensure they are only accessible if logged in.

If the user is not logged in, the requested route will be stored in the session and the user will be redirected to the login page. Upon successful login, the user will be redirected to the previously requested URL (see callback route above).

// lib/middleware/secured.js

module.exports = function () {
  return function secured (req, res, next) {
    if (req.user) { return next(); }
    req.session.returnTo = req.originalUrl;

Create the user profile route

The /user route (the user's profile) should only be accessible if the user is logged in. Use the secured middleware to secure the route.

// routes/users.js

var express = require('express');
var secured = require('../lib/middleware/secured');
var router = express.Router();

/* GET user profile. */
router.get('/user', secured(), function (req, res, next) {
  const { _raw, _json, ...userProfile } = req.user;
  res.render('user', {
    userProfile: JSON.stringify(userProfile, null, 2),
    title: 'Profile page'

module.exports = router;

Index route

If you don't have one yet, create an index route to serve the homepage.

// routes/index.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
  res.render('index', { title: 'Auth0 Webapp sample Nodejs' });

module.exports = router;

Making the user available in the views

In the views and layouts, it is often necessary to conditionally render content depending on if a user is logged in or not. Other times, the user object might be necessary in order to customize the view.

Create a middleware lib/middleware/userInViews.js for this purpose.

// userInViews.js

module.exports = function () {
  return function (req, res, next) {
    res.locals.user = req.user;

Including the routers and userInViews middleware

Include the new routers and the userInViews middleware in your app:

// app.js

var userInViews = require('./lib/middleware/userInViews');
var authRouter = require('./routes/auth');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

// ..
app.use('/', authRouter);
app.use('/', indexRouter);
app.use('/', usersRouter);
// ..

Use locals.user, as implemented in the middleware, to customize the views. For example, we can use it to conditionally render links related to the user session in the layout.

//- views/layout.pug

    // ...
    a(href="/") Home
    if locals.user
      a(href="/user") Profile
      a(href="/logout") Log Out
      a(href="/login") Log In

    // ...
    block content

Implement the user profile view

Create a views/user.pug template. Use locals.user to access the user data in the session.

//- views/user.pug

extends layout

block content
      h1 Welcome #{user.nickname}
      h2 User profile
      p This is the content of <code>req.user</code>.
      p Note: <code>_raw</code> and <code>_json</code> properties have been ommited.
        code #{userProfile}

See it in action

Install the dependencies, start your app and point your browser to http://localhost:3000. Follow the Log In link to log in or sign up to your Auth0 tenant. Upon successful login or signup, you should be redirected to the user's profile page.

Auth0 Universal Login

Use Auth0 for FREE