Tutorial: Implementing Models

Integrating Models
Using The Model In PassportJS

Now that the tricky coding has been accomplished we can focus on how to make use of the ORM and model during our Passport-based authentication.

In addition to the usual invocation of PassportJS previously covered in this tutorial we make a further extension on line 140 of server.js be passing the server variable to our config/passport.js function.

     // Include our PassportJS implementation
     require('./config/passport.js')(passport,server); // Custom passport.js implementation

Whilst the contents of passport.js remain fairly similar to the previous tutorial some modifications have been made to incorporate the upgraded password hashing and ORM model.

// The Essentials
var LocalStrategy = require('passport-local').Strategy; // Local passport strategy
var JwtStrategy = require('passport-jwt').Strategy; // JWT passport strategy
var ExtractJwt = require('passport-jwt').ExtractJwt; // Various JWT extraction methods
var jwt = require('jsonwebtoken'); // Jason Web Tokens
var config = require('config'); // Easy configuration file parser
var crypto = require('crypto'); // Cryptographic library
var hashers = require('node-django-hashers'); // PBKDF2 hasher

Lines 15 through 22 contain much of the standard definitions and on line 22 we include a special library named ‘node-django-hashers’ available from https://github.com/kalvish21/hashers

Using the password hasher and ORM models we can affect changes to the local passport strategy.

  /** Configure the local passport strategy
    *
    * This is very rudementary with hard coded credentials to say the least.
    * Ideally one would veryify a hashed version of these credentials against 
    * a database or some other sort of authentication backend before signing
    * a token */
   passport.use(new LocalStrategy(
       function(username, password, done) {

        app.models.auth_user.findOne({username: username, is_active: 1}, function(err,model) {
          if (err) {
             return done(true,null);
          } else {
                var hash_name = hashers.identifyHasher(model.password);
                var hash_algorithm = hashers.getHasher(hash_name);
                if (hash_algorithm.verify(password, model.password)) {
                   // They check out OK.  Let's go ahead and format a dummy payload and sign it with our JWT.
                   var payload = {username: username, password:password, otherText: 'This is a test message'};
                   jwt.sign(payload, jwtConfig.secretKey, { algorithm: 'HS256', expiresIn:parseInt(jwtConfig.tokenValidity), issuer: 'http://www.yourapiexpert.com', audience: 'http://www.yourapiexpert.com', subject:username}, function(err, token) {
                     if (err) {
                       return done(true, null);
                     } else {
                       return done(null, {token: token});
                     }
                   });
                } else {
                   return done(true,null);
                }
          }
        });

    }));

Between lines 49 and 80 we see a significant re-write of the ‘LocalStrategy’ used for username and password authentication.  Whilst the strategy still issues JWT tokens to successfully authenticated users some significant modification has been made in the authentication method.

On line 58 we see the invocation of ‘app.models.user_auth’ and we will recall that ‘app.models’ is actually the same ‘server.models’ made available during the initialization of the ORM in server.js (lines 136 and 137).  For our authentication strategy we ask the ORM to return us records matching the username where the user is active ({username: username, is_active: 1}).  The ORM makes use of the model and adapter to retrieve the records from the back-end MySQL database.

If authentication is successful lines 62 to 67 continue to generate and issue a JWT token used in the protected endpoints.

Next Up: Integrating Protected Endpoints

Pages: 1 2 3 4 5

Written by YourAPIExpert