Giter Club home page Giter Club logo

node-auth-mini's Introduction

Project Summary

In this project, we'll use passport to handle authenticating users. Passport can use many different strategies to authenticate users. However, we'll take a look at just one of them for this project. We are going to use the auth0 strategy. We'll have to sign-up at manage.auth0.com to get an app (aka client) that we can log in to.

Setup

  • Fork and clone this repository.
  • cd into the project directory.
  • Run npm install.

Step 1

Summary

In this step, we'll install the required dependencies to use passport and the auth0 strategy in a node application.

Instructions

  • Run npm install --save passport passport-auth0.

Solution

Step 2

Summary

In this step, we'll go to manage.auth0.com to create an account and modify the default application they give us.

Instructions

  • Go to manage.auth0.com.
  • Register for an account.
    • Create a domain
      • This can be anything. It will be the url individuals are redirected to when they try to login to your site.
    • Set the account type to Personal.
    • Set the role to Developer.
    • Set the project to Just playing around.
  • Log in to your Auth0 account.
  • Go to Applications using the left navigation bar.
  • Click on Settings for the Default App.
    • Change the Application Type to Machine To Machine.
    • Change the Allowed Callback URLs to http://localhost:3000/login.
    • Change the Allowed Origins to http://localhost:3000
  • Click Save Changes.
  • Keep the page open, we'll need the domain, id, and secret later.

Step 3

Summary

In this step, we'll create a .env file and strategy.js. We'll install and configure the dotenv package and add .env to our .gitignore so we can keep the client domain, id, and secret off of GitHub. We'll then use the properties from .env in strategy.js and configure strategy.js to use the auth0 strategy.

Instructions

  • Install dotenv by running npm install --save dotenv.
  • Create a .env file.
  • Open .env.
    • The file should have DOMAIN, CLIENT_ID, and CLIENT_SECRET properties.
    • The values should equal the values of your domain, clientID, and clientSecret from manage.auth0.com.
  • Add .env to .gitignore.
  • Open index.js.
  • Require and configure dotenv at the top of the file.
  • Create a strategy.js file.
  • Open strategy.js.
  • Require the passport-auth0 strategy in a variable called Auth0Strategy.
  • Use module.exports to export a new Auth0Strategy.
    • Syntax
      module.exports = new Auth0Strategy({
        domain:       '...',
        clientID:     '...',
        clientSecret: '...',
        callbackURL:  '/login',
        scope: 'openid email profile'
        },
        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);
        }
      );
  • Modify the domain, clientID, and clientSecret to use the values from .env.

Solution

strategy.js
const Auth0Strategy = require('passport-auth0');
const { DOMAIN, CLIENT_ID, CLIENT_SECRET } = process.env;

module.exports = new Auth0Strategy({
   domain:       DOMAIN,
   clientID:     CLIENT_ID,
   clientSecret: CLIENT_SECRET,
   callbackURL:  '/login',
   scope: 'openid email profile'
  },
  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);
  }
);

Step 4

Summary

In this step, we'll configure our app to use sessions and passport with our newly created strategy.

Instructions

  • Open index.js.
  • Require passport and strategy from strategy.js.
  • Configure the app to use sessions.
  • Initialize passport and configure passport to use sessions.
  • Configure passport to use our required strategy.

Solution

index.js
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const strategy = require(`${__dirname}/strategy.js`);

const app = express();
app.use( session({
  secret: 'sup dude',
  resave: false,
  saveUninitialized: false
}));
app.use( passport.initialize() );
app.use( passport.session() );
passport.use( strategy );

const port = 3000;
app.listen( port, () => { console.log(`Server listening on port ${port}.`); } );

Step 5

Summary

In this step, we'll use the serializeUser and deserializeUser methods of passport. These methods get called before a successful redirect. We can use these methods to pick what properties we want to store on session.

Instructions

  • Open index.js.
  • Call the passport.serializeUser method and pass in a function as the first argument.
    • This function should have a user and done parameter.
    • This function should call done with null as the first argument and an object as the second argument.
      • Use an object that only has the id, displayName, nickname, and email from user.
  • Call the passport.deserializeUser method and pass in a function as the first argument.
    • This function should should have a obj and done parameter.
      • obj will equal the object we passed into done from serializeUser.
    • This function should call done with null as the first argument and obj as the second argument.
      • After done is finished, the value of obj is then stored on req.user and req.session.passport.user.

Solution

index.js
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const strategy = require(`${__dirname}/strategy.js`);

const app = express();

app.use( session({
  secret: 'sup dude',
  resave: false,
  saveUninitialized: false
}));
app.use( passport.initialize() );
app.use( passport.session() );
passport.use( strategy );

passport.serializeUser(function(user, done) {
  done(null, { id: user.id, display: user.displayName, nickname: user.nickname, email: user.emails[0].value });
});

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});

const port = 3000;
app.listen( port, () => { console.log(`Server listening on port ${port}.`); } );

Step 6

Summary

In this step, we'll create a login endpoint that will call the authenticate method on passport. We'll then configure it to redirect to a /me endpoint on success and the /login endpoint on failure. We'll also enable failureFlash so passport can flash an error message on failure.

Instructions

  • Open index.js.
  • Create a GET endpoint at /login that calls the authenticate method on passport.
    • The first argument should be a string of the strategy: 'auth0'.
    • The second argument should be a configuration object:
      • Add a successRedirect property that equals '/me'.
      • Add a failureRedirect property that equals '/login'.
      • Add a failureFlash property that equals true.

Solution

index.js
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const strategy = require(`${__dirname}/strategy.js`);

const app = express();

app.use( session({
  secret: 'sup dude',
  resave: false,
  saveUninitialized: false
}));
app.use( passport.initialize() );
app.use( passport.session() );
passport.use( strategy );

passport.serializeUser(function(user, done) {
  done(null, { id: user.id, display: user.displayName, nickname: user.nickname, email: user.emails[0].value });
});

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});

app.get( '/login',
  passport.authenticate('auth0',
    { successRedirect: '/me', failureRedirect: '/login', failureFlash: true }
  )
);

const port = 3000;
app.listen( port, () => { console.log(`Server listening on port ${port}.`); } );

Step 7

Summary

In this step, we'll create a /me endpoint that checks to see if req.user exists. If it does, it will send our user object. If it doesn't, it will redirect to the /login endpoint.

Instructions

  • Create a GET endpoint at /me that checks to see if req.user exists.
    • If it does, return a status 200 with the req.user object.
    • If it doesn't, redirect to /login.

Solution

index.js
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const strategy = require(`${__dirname}/strategy.js`);

const app = express();

app.use( session({
  secret: 'sup dude',
  resave: false,
  saveUninitialized: false
}));
app.use( passport.initialize() );
app.use( passport.session() );
passport.use( strategy );

passport.serializeUser(function(user, done) {
  done(null, { id: user.id, display: user.displayName, nickname: user.nickname, email: user.emails[0].value });
});

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});

app.get( '/login',
  passport.authenticate('auth0',
    { successRedirect: '/me', failureRedirect: '/login', failureFlash: true }
  )
);

app.get('/me', ( req, res, next) => {
  if ( !req.user ) {
    res.redirect('/login');
  } else {
    // req.user === req.session.passport.user
    // console.log( req.user )
    // console.log( req.session.passport.user );
    res.status(200).send( JSON.stringify( req.user, null, 10 ) );
  }
});

const port = 3000;
app.listen( port, () => { console.log(`Server listening on port ${port}.`); } );

Step 8

Summary

In this step, we'll open a browser and see if we can log in to our Auth0 client.

Instructions

  • Start your server
  • Open a browser and navigate to http://localhost:3000/login.
  • Sign up for the client and then log in to it.

Solution

Contributions

If you see a problem or a typo, please fork, make the necessary changes, and create a pull request so we can review your changes and merge them into the master repo and branch.

Copyright

© DevMountain LLC, 2017. Unauthorized use and/or duplication of this material without express and written permission from DevMountain, LLC is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to DevMountain with appropriate and specific direction to the original content.

node-auth-mini's People

Contributors

devlemire avatar joeblank avatar steven-isbell avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.