Breached password detection is a critical component of secure applications.    Read the white paper

FusionAuth logo
FusionAuth logo
  • Features
    FusionAuth Reactor

    FusionAuth Reactor is a powerful suite of features developed to extend FusionAuth's core functionality.

    • Flexible Architecture   Flexible Architecture
    • Auth the Way You Want It   Auth the Way You Want It
    • Security & Compliance   Security & Compliance
    • Ultimate Password Control   Ultimate Password Control
    • Customizable User Experience   Customizable User Experience
    • Advanced Registration Forms   Advanced Registration Forms
    • Built for Devs   Built for Devs
    • User Management & Reporting   User Management & Reporting
    • Scalability   Scalability
    • Single Sign-on   Single Sign-on
    • Breached Password Detection   Breached Password Detection
    • Connectors   Connectors
    • FusionAuth Reactor   FusionAuth Reactor
  • Pricing
    Cloud Pricing

    Let us host, monitor, manage, and maintain your deployments in your own private cloud.

    SEE PRICING cloud pricing   See FusionAuth Cloud Pricing
    Editions Pricing

    A powerful set of features with available support that extends FusionAuth's core functionality.

    SEE PRICING edition pricing   See FusionAuth Edition Pricing
    Editions + Cloud

    FusionAuth will handle everything so you can get back to building something awesome.

    GET STARTED Get started
  • Docs
  • Downloads
  • Resources
    FusionAuth Resources
    • Upgrade from SaaS
    • Upgrade from Open Source
    • Upgrade from Home Grown
    • Blog   Blog
    • Forum   Forum
    • Community & Support   Community & Support
    • Customer & Partners   Customers & Partners
    • Video & Podcasts   Videos & Podcasts
    • Getting Started   Getting Started
  • Expert Advice
    Expert Advice for Developers

    Learn everything you need to know about authentication, authorization, identity, and access management from our team of industry experts.

    • Authentication   Authentication
    • CIAM   CIAM
    • Identity Basics   Identity Basics
    • OAuth   OAuth
    • Security   Security
    • Tokens   Tokens
    • Dev Tools   Dev Tools
  • Account
Navigate to...
  • Welcome
  • Getting Started
  • 5-Minute Setup Guide
  • Reactor
  • Core Concepts
    • Overview
    • Users
    • Roles
    • Groups
    • Registrations
    • Applications
    • Tenants
    • Identity Providers
    • Authentication and Authorization
    • Integration Points
    • Roadmap
  • Installation Guide
    • Overview
    • System Requirements
    • Server Layout
    • Cluster
    • Docker
    • Fast Path
    • Kickstart™
    • Homebrew
    • Packages
    • Database
    • FusionAuth App
    • FusionAuth Search
    • Securing
    • Upgrading
  • APIs
    • Overview
    • Authentication
    • Errors
    • Actioning Users
    • Applications
    • Audit Logs
    • Connectors
      • Overview
      • Generic
      • LDAP
    • Consent
    • Emails
    • Event Logs
    • Families
    • Forms
    • Form Fields
    • Groups
    • Identity Providers
      • Overview
      • Apple
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Twitter
      • OpenID Connect
      • SAML v2
      • External JWT
    • Integrations
    • JWT
    • Keys
    • Lambdas
    • Login
    • Passwordless
    • Registrations
    • Reports
    • System
    • Tenants
    • Themes
    • Two Factor
    • Users
    • User Actions
    • User Action Reasons
    • User Comments
    • Webhooks
  • Client Libraries
    • Overview
    • Dart
    • Go
    • Java
    • JavaScript
    • .NET Core
    • Node
    • PHP
    • Python
    • Ruby
    • Typescript
  • Themes
    • Overview
    • Localization
    • Examples
  • Email & Templates
    • Overview
    • Configure Email
    • Email Templates
  • Events & Webhooks
    • Overview
    • Events
    • Writing a Webhook
    • Securing Webhooks
  • Example Apps
    • Overview
    • Go
    • Java
    • JavaScript
    • .NET Core
    • PHP
    • Python
    • Ruby
  • Lambdas
    • Overview
    • Apple Reconcile
    • External JWT Reconcile
    • Facebook Reconcile
    • Google Reconcile
    • HYPR Reconcile
    • JWT Populate
    • LDAP Connector Reconcile
    • LinkedIn Reconcile
    • OpenID Connect Reconcile
    • SAML v2 Populate
    • SAML v2 Reconcile
    • Twitter Reconcile
  • Identity Providers
    • Overview
    • Apple
    • Facebook
    • Google
    • HYPR
    • LinkedIn
    • Twitter
    • OpenID Connect
      • Overview
      • Azure AD
      • Github
      • Discord
    • SAML v2
      • Overview
      • ADFS
    • External JWT
      • Overview
      • Example
  • Connectors
    • Overview
    • Generic Connector
    • LDAP Connector
    • FusionAuth Connector
  • Integrations
    • Overview
    • CleanSpeak
    • Kafka
    • Twilio
  • OpenID Connect & OAuth 2.0
    • Overview
    • Endpoints
    • Tokens
  • SAML v2 IdP
    • Overview
    • Google
    • Zendesk
  • Plugins
    • Writing a Plugin
    • Password Encryptors
  • Guides
    • Overview
    • Advanced Registration Forms
    • Breached Password Detection
    • Migration
    • Passwordless
    • Securing Your APIs
    • Silent Mode
    • Single Sign-on
  • Tutorials
    • Overview
    • Setup Wizard & First Login
    • Register/Login a User
    • Migrate Users
    • JSON Web Tokens
    • Authentication Tokens
    • Start and Stop FusionAuth
    • Switch Search Engines
    • User Account Lockout
    • Two Factor
  • Reference
    • CORS
    • Configuration
    • Data Types
    • Known Limitations
    • Password Encryptors
  • Release Notes
  • Troubleshooting

5-Minute Setup Guide

This is a 5-minute guide to set up and integrate with FusionAuth. Starting…​ now!

At the end of this guide, you’ll have a running Node application which will use FusionAuth for authentication, authorization and user management.

Requirements

This guide assumes that you have installed either a MySQL or PostgreSQL database and have a superuser name and password for the database that is able to create schemas and databases. If you do not have a database installed, follow the instructions in our Database Installation Guide to install a database.

You also need to have Node installed. This code has been tested with node 14, but should work with other versions.

Testing Node Installation
$ node -v
v14.4.0
Testing Postgresql Installation
$ psql --version
psql (PostgreSQL) 12.3

Overview

Here are the steps that we need to take to setup FusionAuth as a login provider (also known as an identity provider) for your application:

  1. Install FusionAuth

  2. Start FusionAuth

  3. Complete Maintenance Mode

  4. Complete the Setup Wizard

  5. Create an Application and configure the OAuth settings

  6. Copy the OAuth login URL and add it to your application

  7. Grant the user permissions to your application

  8. Write a route (controller, action, etc) in your backend application that completes the login

  9. Store the user object in the session

  10. Test the application

Steps similar to these will be used for integrating with any OAuth identity provider. These also work for an OpenID Connect (OIDC) identity provider. Since FusionAuth supports both OAuth and OIDC, we’ll use the latter since it is the modern standard. Let’s get into the details of each step.

You can also watch a video of this tutorial:

1. Install FusionAuth

FusionAuth is simple to set up on your laptop, desktop or any server. You can also purchase a basic hosting plan on the FusionAuth Cloud platform.

Our installation guide covers all of the different methods you can use to install FusionAuth including Docker, Homebrew, Debian packages and our quick start script. You can follow any of the methods in the installation guide. For this document, we’ll use the Fast Path installation process using one of the commands below. You may optionally install Elasticsearch to be used as the user search engine.

macOS

Install in your current working directory using ZIP packages
sh -c "curl -fsSL https://raw.githubusercontent.com/FusionAuth/fusionauth-install/master/install.sh | sh"
Install in your current working directory using ZIP packages, include Elasticsearch
sh -c "curl -fsSL https://raw.githubusercontent.com/FusionAuth/fusionauth-install/master/install.sh | sh -s - -s"

Linux

Install in your current working directory using ZIP packages
sh -c "curl -fsSL https://raw.githubusercontent.com/FusionAuth/fusionauth-install/master/install.sh | sh -s - -z"
Install in your current working directory using ZIP packages, include Elasticsearch
sh -c "curl -fsSL https://raw.githubusercontent.com/FusionAuth/fusionauth-install/master/install.sh | sh -s - -z -s"
Install for all users on the system using DEB or RPM packages, requires sudo access
sh -c "curl -fsSL https://raw.githubusercontent.com/FusionAuth/fusionauth-install/master/install.sh | sh"
Install for all users on the system using DEB or RPM packages, include Elasticsearch, requires sudo access
sh -c "curl -fsSL https://raw.githubusercontent.com/FusionAuth/fusionauth-install/master/install.sh | sh -s - -s"

Windows

Install in your current working directory using ZIP packages
. { iwr -useb https://raw.githubusercontent.com/FusionAuth/fusionauth-install/master/install.ps1 } | iex; install
Install in your current working directory using ZIP packages, include Elasticsearch
. { iwr -useb https://raw.githubusercontent.com/FusionAuth/fusionauth-install/master/install.ps1 } | iex; install -includeSearch 1

Once the Fast Path installer completes, we will see this output on the console:

Fast Path install complete
Downloading zip packages
######################################################################## 100.0%
######################################################################## 100.0%
Installing packages

Install is complete. Time for tacos.

 1. To start FusionAuth run the following command
    /Users/bpontarelli/dev/example/fusionauth/bin/startup.sh

 2. To begin, access FusionAuth by opening a browser to http://localhost:9011

 3. If you're looking for documentation, open your browser and navigate to https://fusionauth.io/docs

Thank you have a nice day.

2. Start FusionAuth

The next step is to start FusionAuth using the command that the Fast Path installer created. This script is called startup.sh and we can execute it from the installation directory like this:

Startup script
fusionauth/bin/startup.sh

This will start both the fusionauth-app component as well as the fusionauth-search component if you downloaded the Elasticsearch option. (Here’s a document on how to choose whether to do so.)

If you are on Windows, you’ll need to use the startup.bat file instead.

3. Complete Maintenance Mode

After we have FusionAuth installed and running, we can open our browser to http://localhost:9011. This is the default address for FusionAuth when running locally. This will bring up FusionAuth, which should be sitting in Maintenance Mode and ready to be configured.

FusionAuth enters Maintenance Mode any time the database is not accessible or is not properly set up. In our case, FusionAuth was able to connect, but the system was not configured. Here’s how the Maintenance Mode screen should look:

Maintenance Mode Database

Here we need to provide the super user credentials for our database along with the name of the host of the database is running on if it isn’t running locally. We can also select either MySQL or PostgreSQL and change the database port if needed. For our example, we will be using PostgreSQL on the standard port with a super username of postgres and a password of password. We can also change the username and password that will be created as the primary database account that FusionAuth will access, the fusionauth user above.

The reason that FusionAuth uses a separate username and password to connect to the database during normal operation is that if the FusionAuth configuration file is compromised and an attacker learns our database username and password, they will only have access to the FusionAuth database. This is helpful if we are using a single database server for multiple applications and databases. This is known as the principle of least privilege and FusionAuth uses this principle whenever possible.

Once we click the Submit button, we will be taken to the next step of Maintenance Mode. If you have opted to install with Elasticsearch, this step is where the FusionAuth Search component is configured, otherwise you can skip ahead to step 4, the Setup Wizard.

Our Fast Path install and startup script automatically start the fusionauth-search component, which is a standard version of Elasticsearch. Since FusionAuth is able to connect to this search engine, all that is needed is to create the indexes inside it. This page looks like this:

Maintenance Mode Search

Clicking the Submit button here will cause FusionAuth to exit Maintenance Mode and begin starting up. We’ll see an interstitial page that looks like this:

Interstitial

4. Complete the Setup Wizard

Once FusionAuth starts up successfully, we will be taken to the Setup Wizard. This is where we will create the administrator account for FusionAuth and accept the license.

Record the email and password you choose for the administrator account. You won’t be able to recover this without setting up an email server, which is beyond the scope of this tutorial.

We can also sign up for the FusionAuth newsletter, which is a great way to stay up-to-date on FusionAuth releases and new features. We never pitch you, hard-sell or sell your information, so feel free to sign up. Here’s what the Setup Wizard page looks like:

Setup Wizard

Clicking Submit here will complete the Setup Wizard and log us into the FusionAuth admin UI.

5. Create an Application and configure the OAuth settings

Once we arrive in the FusionAuth admin UI, the first thing we need to do is create an Application. An Application is something that a user can log into. This is the application we are building or that we are migrating to use FusionAuth. We’ll click the Application menu option on the left side of the page or the Setup button in the box at the top of the page.

Dashboard to Applications

This will take us to the listing page for Applications. Next, we’ll click the green plus button (the add button) at the top of the page:

Application Listing

On the Application form, we’ll need to provide a name for our Application (only used for display purposes) and a couple of items on the OAuth tab. We’ll start with a simple setup that allows existing users to log into your application. Therefore, we won’t need to define any roles or registration configuration. If we click on the OAuth tab, we’ll see these options:

Application Form

Most of the defaults will work, but we also need to provide these items:

  • An authorized redirect URL. This is the route/controller in our application’s backend that will complete the OAuth workflow. In our example, we set this to http://localhost:3000/oauth-redirect. We’ll show some Node.js example code below for this route.

  • Optionally, we can specify a valid Logout URL. This is where the user will be redirected to after they are logged out of FusionAuth’s OAuth front-end: our application.

  • We need to ensure that the Authorization Code grant is selected in the Enabled Grants.

Once we have all of this configured, we’ll click the blue Save button at the top of the page.

6. Copy the OAuth login URL and add it to your application

Once the Application has been created, we’ll be back on the listing page. From here, we can click the green View button for our new Application. This will open a dialog that contains information about the Application, including the full URL for the OAuth login page. We’ll copy this URL and paste it into our application’s HTML as a link for the user to login. Most applications have a link that says, "Login" or "My Account" for this action.

Here’s how the view dialog looks:

Application View Dialog

We can add this URL as a link to our Node.js example application in the main template. The code is available on the FusionAuth GitHub, and it’s recommended you download it to follow along.

Here’s how our Pug template, which lives in views/index.pug, looks:

Pug Template
extends layout

block content
  h1= title
  if user
    p Hello #{user.firstName}
  else
    a(href='http://localhost:9011/oauth2/authorize?client_id='+clientId+'&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Foauth-redirect&scope=offline_access&state='+stateValue+'&code_challenge='+challenge+'&code_challenge_method=S256') Login

  p Welcome to #{title}

If you are using raw HTML, here’s an anchor tag that will start the OAuth workflow the same as the Pug template above:

HTML Snippet
<a href="http://localhost:9011/oauth2/authorize?client_id=48cf2492-508d-4644-95eb-3741618821a4&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Foauth-redirect">Login</a>

Just drop this anchor tag into your HTML page and it will take the user to FusionAuth to login.

7. Grant the user permissions to your application

Next, we need to grant the user we created in the Setup Wizard permissions to log into our new Application. This can be done from the User management section of the FusionAuth admin UI. By clicking the Users link in the navigation, we’ll be taken to the main user search. Since we only have one user in FusionAuth at the moment, we’ll just click on that user:

User Search

Once we are in this user’s account, we’ll click the Add Registration button. This will take us to a page that will allow us to add a registration for this user to the new Application. Here’s what this looks like:

Registration Add Form

For this example, we don’t need to provide any additional information for the registration, so we can just click the save button at the top. Now the user is set up so that they can log into the application. Keep in mind that in most cases, the process of creating a registration is done when the user signs up for our application.

Therefore, the process we just used is normally not required in order for users to log in. However, this process can be used for applications that are closed systems such as internal applications for your company. In these cases, users will be manually granted permissions to each application by an administrator.

8. Write a route (controller, action, etc) in your backend application that completes the login

Before we test the login, let’s write the route/controller in our application’s backend that will complete the OAuth workflow. After a user logs into FusionAuth’s OAuth front-end successfully, their browser will be redirected to the URL we provided in the configuration step above. This redirect will contain a query parameter called code that contains the OAuth authorization code from FusionAuth. Our route/controller will use this code parameter to call back to FusionAuth to exchange the code for an access token.

In order to complete this process, we’ll be using the FusionAuth typescript client library along with Express and Pug templates. This code is available on the FusionAuth GitHub. Here’s how our package.json file looks:

package.json
{
  "name": "fusionauth-node-example",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "@fusionauth/typescript-client": "^1.22.0",
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "express-session": "1.17.0",
    "http-errors": "~1.6.3",
    "morgan": "~1.9.1",
    "pkce-challenge": "^2.1.0",
    "pug": "2.0.0-beta11"
  }
}

You’ll want to install this all by running npm install after creating the above package.json file.

Here’s the entire Express router. You want to create a file called routes/index.js and put this code in it:

Node.js Express Router
const express = require('express');
const router = express.Router();
const {FusionAuthClient} = require('@fusionauth/typescript-client');
const clientId = '48cf2492-508d-4644-95eb-3741618821a';
const clientSecret = 'm-WaqEcvIIzghwy_uVtxoqFtVSrLoDpU76gG2V9RPX8';
const client = new FusionAuthClient('noapikeyneeded', 'http://localhost:9011'); // only using public api methods
const pkceChallenge = require('pkce-challenge');

/* GET home page. */
router.get('/', function (req, res, next) {
  const stateValue = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
  req.session.stateValue = stateValue;

  //generate the pkce challenge/verifier dict
  pkce_pair = pkceChallenge();
  // Store the PKCE verifier in session
  req.session.verifier = pkce_pair['code_verifier'];
  const challenge = pkce_pair['code_challenge'];
  res.render('index', {user: req.session.user, title: 'FusionAuth Example', clientId: clientId, challenge: challenge, stateValue: stateValue});
});

/* OAuth return from FusionAuth */
router.get('/oauth-redirect', function (req, res, next) {
  const stateFromServer = req.query.state;
  if (stateFromServer !== req.session.stateValue) {
    console.log("State doesn't match. uh-oh.");
    console.log("Saw: " + stateFromServer + ", but expected: " + req.session.stateValue);
    res.redirect(302, '/');
    return;
  }

  // This code stores the user in a server-side session
 client.exchangeOAuthCodeForAccessTokenUsingPKCE(req.query.code,
                                                 clientId,
                                                 clientSecret,
                                                 'http://localhost:3000/oauth-redirect',
                                                 req.session.verifier)
      .then((response) => {
        return client.retrieveUserUsingJWT(response.response.access_token);
      })
      .then((response) => {
        // check for authorization
        if (!response.response.user.registrations || response.response.user.registrations.length == 0 || (response.response.user.registrations.filter(reg => reg.applicationId === clientId)).length == 0) {
          console.log("User not registered, not authorized.");
          res.redirect(302, '/');
          return;
        }

        req.session.user = response.response.user;
      })
      .then((response) => {
        res.redirect(302, '/');
      }).catch((err) => {console.log("in error"); console.error(JSON.stringify(err));});

});

module.exports = router;

This is a lot, so you can just cut and paste it. But let’s look at one specific portion of it. We need a route that will respond to the path we configured in the FusionAuth admin user interface above (/oauth-redirect). This route will pull the code parameter from the request and exchange it for an access token.

In order to call the function on the FusionAuth client, we will also need the client_id and the client_secret from our Application configuration above. These are required so that our application can prove it is the correct application the user is logging into. Here’s an excerpt of the Node.js code for the route:

Node.js Route
/* OAuth return from FusionAuth */
const clientId = '48cf2492-508d-4644-95eb-3741618821a';
const clientSecret = 'm-WaqEcvIIzghwy_uVtxoqFtVSrLoDpU76gG2V9RPX8';
//...
router.get('/oauth-redirect', function (req, res, next) {
  //...
  client.exchangeOAuthCodeForAccessToken(req.query.code,
                                         clientId,
                                         clientSecret,
                                         'http://localhost:3000/oauth-redirect',
                                         req.session.verifier)
});

If you don’t want to use a client library, you may post directly to the /oauth2/token endpoint. This will return the access token as well as other data.

9. Store the user object in the session

The final step is to add some code to our route that will retrieve the User object from FusionAuth using the access_token we retrieved in the previous step. Once we have the User object, we will store it in a server side session so that it can be used in other parts of the application. We also check that the user has been registered to our application.

We can also store the access_token from FusionAuth as a cookie if our application would rather push the state to the browser. In either case, the last step we take is to redirect the authorized user back to the homepage. Here’s the complete code for exchanging the token, retrieving the user and storing it in the session:

Node.js Route Complete
const clientId = '48cf2492-508d-4644-95eb-3741618821a';
const clientSecret = 'm-WaqEcvIIzghwy_uVtxoqFtVSrLoDpU76gG2V9RPX8';
//...
/* OAuth return from FusionAuth */
router.get('/oauth-redirect', function (req, res, next) {
  //...
  client.exchangeOAuthCodeForAccessToken(req.query.code,
                                         clientId,
                                         clientSecret,
                                         'http://localhost:3000/oauth-redirect')
      .then((response) => {
        return client.retrieveUserUsingJWT(response.successResponse.access_token);
      })
      .then((response) => {
        if (!response.response.user.registrations || response.response.user.registrations.length == 0 || (response.response.user.registrations.filter(reg => reg.applicationId === clientId)).length == 0) {
          console.log("User not registered, not authorized.");
          res.redirect(302, '/');
          return;
        }
        req.session.user = response.successResponse.user;
      })
      .then(() => {
        res.redirect(302, '/');
      });
});

10. Test the application

Now that everything is written, let’s test the workflow. We can fire up the Node.js backend using this command:

Node.js Command
npm start

If we open our application in the browser and click the Login link, this will take us to FusionAuth’s OAuth login page. From here, we can log in with the account we created in step 4, the Setup Wizard.

As mentioned above, the Node.js code above is available on the FusionAuth GitHub located here: https://github.com/FusionAuth/fusionauth-node-example .

Cookies for a Single Page Application

If you prefer to use cookies rather than server-side sessions, you can change the code for your oauth-redirect route to this code:

Node.js Route Complete With Cookie Token Storage
const clientId = '48cf2492-508d-4644-95eb-3741618821a';
const clientSecret = 'm-WaqEcvIIzghwy_uVtxoqFtVSrLoDpU76gG2V9RPX8';
//...
/* OAuth return from FusionAuth */
client.exchangeOAuthCodeForAccessToken(req.query.code,
                                       clientId,
                                       clientSecret,
                                       'http://localhost:3000/oauth-redirect',
                                       req.session.verifier)
  .then((response) => {
    res.cookie('access_token', response.successResponse.access_token, {httpOnly: true});
    res.cookie('refresh_token', response.successResponse.refresh_token, {httpOnly: true});
    res.redirect(302, '/');
  });

This code works well if you are building a single-page application (SPA) or any other type of application that uses cookies rather than server-side sessions.

Feedback

We are beginning to work on a ten minute guide and a 42 minute guide. What topics would you want to learn next? Please choose two at most.

Next Steps

From here, you can begin creating a registration page in your application or using FusionAuth’s registration tool. You can also start working with FusionAuth Themes to make the login pages look like your brand. If you want to use FusionAuth’s forgot password system, you will need to configure an SMTP server. Here are some links to additional documents that will help you continue your integration with FusionAuth.

  • Core Concepts

  • Themes

  • Emails

  • Additional OAuth documentation

  • Setting up Two-Factor

  • Registration API

Feedback

How helpful was this page?

See a problem?

File an issue in our docs repo

Quick Links

  • Download
  • Cloud Pricing
  • Editions Pricing
  • Contact Us
  • Jobs (come work with us)
  • My Account

Resources

  • Docs
  • Blog
  • Community & Support
  • Upgrade from SaaS
  • Upgrade from Homegrown
  • Upgrade from Open Source

Everything Else

  • Privacy Policy
  • Product Privacy Policy
  • License
  • License FAQ
  • Enterprise Sales FAQ
  • Security (contact, bug bounty, etc)
  • Technical Support

Connect with Us

logo
Subscribe for Updates
We only send dev friendly newsletters. No marketing fluff!
© 2021 FusionAuth