JS-301-NodeServer
  • Introduction
  • js_library
    • Node Server
      • 00 - Intro
        • 01 - Purpose
        • 02 - Back-End Setup
        • 03 - Terms Cheat Sheet
      • 01 - Server Set up
        • 01 - npm packages
        • 02 - Express Intro
        • 03 - Express code
      • 02 - Development Tools
        • 01 - Nodemon Intro
        • 02 - Postman Intro
        • 03 - Postman set up
      • 03 - Routes Intro
        • 01 - Routes intro
        • 02 - Express Router() intro
        • 03 - Challenge 1
        • 04 - Challenge 2
      • 04 - Database Intro
        • 00 - DB Intro and Set up
          • 00 - DB Intro
          • 01 - PostgreSQL Intro
          • 02 - Install
        • 01 - Sequelize Intro
          • 01 - Sequelize intro
          • 02 - Initialize
      • 05 - Model View Controller
        • 01 - MVC
          • 00 - MVC Intro
        • 02 - Models
          • 01 - Intro to Models
          • 02 - Test Model
        • 03 - Controllers
          • 00 - Controllers Intro
          • 01 - Controller Set up
          • 02 - Create Method
          • 03 - req.body()
          • 04 - Crafting the Response
          • 05 - Sending the Response
          • 06 - JSON Response
          • 07 - Error Handling
        • 04 - Conclusion
      • 06 - Tokenization
        • 01 - JWT Intro
          • 01 - JWT intro
        • 02 - User Create
          • 01 - User Create
          • 02 - Refactor
        • 03 - User Token
          • 01 - JWT Package
          • 02 - Adding JWT
          • 03 - ENV
      • 07 - Encryption
        • 01 - bcrypt
        • 02 - bcrypt setup
      • 08 - Session
        • 00 - Session Intro
        • 01 - Sign In Method
        • 02 - Sign In Bcrypt
        • 03 - Sign In JWT
      • 09 - Middleware
        • 01 - Test Client HTML
        • 02 - Test Client JS
        • 03 - Middleware intro
        • 04 - Headers intro
        • 05 - Server Update
        • 06 - Test Post
        • 07 - Test Post Refactor
        • 08 - Post Data
        • 09 - Fetch From One
      • 10 - Authenticated Routes
        • 01 - Intro to Authenticated Routes
        • 02 - Validate Session
        • 03 - Changes to app.js
        • 04 - authtestcontroller.js
        • 05 - Delete an Item
        • 06 - Update an Item
        • 07 - Postman Testing
      • 11 - Authenticated Requests
        • 00 - Additions to index
        • 01 - Anatomy of a Request
        • 02 - Create User
        • 03 - Getting a Token
        • 04 - Get Items From One User
        • 05 - Creating an Item for a User
        • 06 - Get one item
        • 07 - Update an Item
        • 08 - Deleting an Item
        • 09 - Deleting with a Custom Event
      • 12 - Workout Log Server
        • 00 - Intro
      • 13 - More Sequelize Functions
        • Migrations
          • 00 - Intro
          • 01 - init and config
          • 02 - Creating the First Migration
          • 03 - Running Migrations
          • 04 - Reverting Migrations
          • 05 - Seeds
          • 06 - Reverting Seeds
        • Queries
          • 00 - Intro
          • 01 - Queries
Powered by GitBook
On this page
  • Files
  • Code
  • What Just Happened?
  • Before You Move On
  1. js_library
  2. Node Server
  3. 10 - Authenticated Routes

02 - Validate Session

In this module, we'll construct a file that will check to see if the request has a token attached.

Files

Please add the following to your server in the middleware folder:

    └── 5-Express Server
            └── server
                └── controllers
                └── middleware
                    └── headers.js
                    └── validate-session.js <----- ADD THIS              
                └── models
            └── client

Code

Put the following code inside of validate-session.js. There is a little bit of code that is commented out here, leave it like that for now.

var jwt = require('jsonwebtoken');
var sequelize = require('../db');
var User = sequelize.import('../models/user');

module.exports = function(req, res, next) {
    // if (req.method == 'OPTIONS') {
    //     next()
    // } else {
        var sessionToken = req.headers.authorization; //1
        console.log(sessionToken) //2
        if (!sessionToken) return res.status(403).send({ auth: false, message: 'No token provided.' }); //3
        else { //4
            jwt.verify(sessionToken, process.env.JWT_SECRET, (err, decoded) => { //5
                if(decoded){
                    User.findOne({where: { id: decoded.id}}).then(user => { //6
                        req.user = user; //7
                        next();
                    },
                    function(){ //8
                        res.status(401).send({error: 'Not authorized'});
                    });
                } else { //9
                    res.status(400).send({error: 'Not authorized'});
                }
            });
        }
    //}
}

What Just Happened?

  1. The variable sessionToken is created to hold the token, which is pulled from the authorization header of the request coming in.

  2. The token is printed to the console. This is purely for debugging purposes to verify that the token is being sent to the server. It should not be left in the final code, as it is a potential security vulnerability.

  3. If no token is present, the 403 Forbidden error is returned as the response. We have several different error handling responses in this file, so assigning each a different error code or message is a big help in debugging.

  4. No user property is ever provided in the request, so only tokens will get checked. This prevents unauthorized use of a token that was assigned to a different user.

  5. The verify method decodes the token with the provided secret, then sends a callback with two variables. If successful, decoded will contain the decoded payload; if not, decoded remains undefined. err is null by default.

  6. If decoded has a value, the Sequelize findOne method looks for an id in the users table that matches the decoded.id property. This value is then passed into a callback.

  7. The callback sets the user value for the request as the id value passed to it then sends the request on to its next destination. This property will be necessary later in adding to the database.

  8. If no matching id is found, an error message is thrown.

  9. If no value for decoded, an error message is thrown.

Before You Move On

Go back and read through all that again. Make a flow chart of what's happening. Explain to a partner what is going on. Do whatever you need to do in order to understand this file. This is some very deep, very detailed code that can be tough to understand. Security should be your #1, #2, and #3 priorities when coding, so it's worth the extra time to get it right.

Previous01 - Intro to Authenticated RoutesNext03 - Changes to app.js

Last updated 7 years ago

There's a lot here, so take it slow through this explanation. Additional information on the verify method can be found .

here