---
agentTools:
  projectIndex: https://docs.swoopnow.com/llms.txt
---

# Javascript - Node

This tutorial will walk you through creating a simple Node + Express application using Swoop for user authentication.

You can download the comprehensive [Starter Example Here](https://github.com/Swoop-Password-Free/express-4.x-swoop-example) if you prefer.

Before you begin, make sure you head to the [Swoop Dashboard](https://dashboard.swoop.email) and create a new property.

[block:image]
{
  "images": [
    {
      "image": [
        "https://files.readme.io/4550fc0-dashboard_add_property_screenshot.png",
        "dashboard add property screenshot.png",
        2396,
        272,
        "#f4f8f7"
      ],
      "caption": "Click the 'Add Property' button on the top right of the dashboard landing page."
    }
  ]
}
[/block]

[block:image]
{
  "images": [
    {
      "image": [
        "https://files.readme.io/f53a531-New_Property_Form_Screenshot.png",
        "New Property Form Screenshot.png",
        2398,
        768,
        "#fbfcfc"
      ],
      "caption": "Then fill in the property fields and submit. Make sure to set the **Redirect URL** to the following to work with our test project:\n`http://localhost:3000/auth/swoop/callback`."
    }
  ]
}
[/block]

\#1. Setting Up the Basic Express App

We are going to make a simple app that has one protected route called **swoop\_test**.

[block:code]
{
  "codes": [
    {
      "code": "mkdir swoop_test\ncd swoop_test\nnpm init -y\ntouch index.js",
      "language": "shell"
    }
  ]
}
[/block]

This will create a basic Node app.  Now we are going to add Express in order to set up routes.

\#2. Creating a Basic Express Server

Start by installing `express` and `express-session`.

[block:code]
{
  "codes": [
    {
      "code": "npm install --save express express-session",
      "language": "shell"
    }
  ]
}
[/block]

Now, open **index.js** and add the following code:

[block:code]
{
  "codes": [
    {
      "code": "const express        = require('express');\nconst app            = express()\nconst port           = process.env.PORT || 3000;\n\n/*****************\n* Routes\n*****************/\n\n// Root Route\napp.get('/', (req, res) => {\n  res.send('Hello Swoop! \\\n  <div><a href=\"/auth/swoop\">Login</a></div> \\\n  <div><a href=\"/logout\">Logout</a></div>');\n});\n\n// Route that will be made secret\napp.get('/secret', (req, res, next) => {\n  res.send('Shhhhhh! It\\' a secret!');\n});\n\n// Start the server\napp.listen(port, () => console.log(`Swoop Demo listening on port ${port}!`));",
      "language": "javascript"
    }
  ]
}
[/block]

Run this code by executing the following command in the terminal:

[block:code]
{
  "codes": [
    {
      "code": "node index.js",
      "language": "shell"
    }
  ]
}
[/block]

This will create a basic Express server that has two routes: a root route and a secret route.  Open your browser to `http://localhost:3000/secret` and you will see the output "Shhhhh! It's a secret!".  We will now set up Swoop to secure this route and require a user to login to view this resource.

\#3. Setting Up Passport for Swoop

Open the terminal and install the following node modules:

[block:code]
{
  "codes": [
    {
      "code": "npm install --save passport passport-swoop",
      "language": "shell"
    }
  ]
}
[/block]

We are using a [Passport.js](http://www.passportjs.org/) strategy for Swoop to help us with the OAuth integration.  Given a little configuration, it will help us generate the OAuth link to send our users to Swoop and will handle the callback when Swoop sends the authorization code.

Add the following code to the top of **index.js**:

[block:code]
{
  "codes": [
    {
      "code": "// Previous imports...\nconst passport       = require('passport');\nconst SwoopStrategy  = require('passport-swoop')\n\n/*****************\n* Middleware\n*****************/\napp.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true }));\napp.use(passport.initialize());\napp.use(passport.session());\n\n// Routes...",
      "language": "javascript"
    }
  ]
}
[/block]

This imports the Passport module and the SwoopStrategy from Passport.  Lastly, we set up a "Middleware" section to our code.  This sets up the session management middleware for our application.  We need to use sessions in order to support the more secure [PKCE](https://oauth.net/2/pkce/) extension of OAuth.

Now we are going to configure Passport with the Swoop parameters.  Add the following code AFTER the Middleware section:

[block:code]
{
  "codes": [
    {
      "code": "// Middleware...\n\n/*****************\n* Passport Config\n*****************/\npassport.use(new SwoopStrategy({\n    clientID: 'CLIENT_ID',\n    clientSecret: 'CLIENT_SECRET',\n    callbackURL: '/auth/swoop/callback'\n  },\n  function(profile, cb) {\n    return cb(null, profile);\n  }));\n\npassport.serializeUser(function(user, cb) {\n  cb(null, user);\n});\n\npassport.deserializeUser(function(obj, cb) {\n  cb(null, obj);\n});\n\n// Routes...",
      "language": "javascript"
    }
  ]
}
[/block]

We are setting up a new SwoopStrategy for Passport with the configuration for your Swoop property.  There are 3 properties here to pay attention to:

* **CLIENT\_ID**  The Client ID associated with your Swoop Property.
* **CLIENT\_SECRET** The Client Secret that was generated for your Swoop Property.
* **CALLBACK\_URL** You need to make sure that this matches the value you used when setting up the property.  You can add multiple callback URLs in the Swoop Dashboard for local, production, etc.

The second part of this method is passed a `profile` from Passport.  It contains the email (`profile.email`) and ID (`profile.id`) or the user. This method is where you might look up your actual user in the database and pass it to the done callback. This way, it will be available on all routes as `req.user`.

The `profile` object also contains the following information, which conforms to the [Open ID Connect standard](https://openid.net/) in the `_json` field:

[block:code]
{
  "codes": [
    {
      "code": "{\n  iss: 'https://auth.swoop.email',\n  sub: '5e1f6bfe587c1a00046b98da',\n  aud: 'swoop_pdkhq4k87gd75p',\n  nonce: 'S_on5v1avdi',\n  email: 'demo@swoop.email',\n  iat: 1585255245,\n  exp: 1586119245\n}",
      "language": "json"
    }
  ]
}
[/block]

Finally, the code above tells express how to serialize and de-serialize a user.  For now, this is just the user object returned from Swoop. In a production environment, it should be the user from your database with a matching email address or Swoop ID.

# 4 Create the Swoop Routes

You might have noticed that clicking on the **login** and **logout** links on the root route results in 404 pages. We are going to implement two routes to complete the OAuth2 process.

Add the following code to the "Routes" section of **index.js**:

[block:code]
{
  "codes": [
    {
      "code": "// Oauth 2 Config...\n\n// Swoop Login Route\napp.get('/auth/swoop', passport.authenticate('swoop', { scope: ['email'] }));\n\n// Callback function after authentication occurs\napp.get('/auth/swoop/callback',\n        passport.authenticate('swoop', { session: true }),\n        (req, res, next) => {\n  res.redirect('/secret');\n});\n\n// Logs the user out and redirects to the homepage\napp.get('/logout', (req, res) => {\n  req.logout();\n  res.redirect('/');\n});\n\n// Routes...",
      "language": "javascript"
    }
  ]
}
[/block]

Now, restart the server and head over to `http://localhost:3000` and click **Login**.

[block:code]
{
  "codes": [
    {
      "code": "node index.js",
      "language": "shell"
    }
  ]
}
[/block]

Congratulations! You are now authenticating users with Swoop.  The last piece of this puzzle is to persist user logins inside of a session in order to protect our secret route.

Now you can use `req.user` in ANY route that you want to secure.

# 5. Securing the Secret Route

Update the secret route code to the following:

[block:code]
{
  "codes": [
    {
      "code": "// Routes...\n\napp.get('/secret', (req, res, next) => {\n  if(req.user) {\n    res.send('This contains a secret. Welcome ' + req.user.email);\n  } else {\n    res.redirect('/');\n  }\n});",
      "language": "javascript"
    }
  ]
}
[/block]

Now when the user attempts to open "/secret", it will redirect them to the homepage unless they have logged in.  If the user is logged in, their email will be accessible when they view **req.user**.

Restart the server and go through the login flow again.

[block:code]
{
  "codes": [
    {
      "code": "node index.js",
      "language": "shell"
    }
  ]
}
[/block]

You are now able to secure ANY route using the Swoop authentication service. Yippee!