User Authentication in SailsJS

By | 04/12/2020

When creating a new application Sails gives you the option to build a fully fledged web app including user log in and authentication as well as stripe integration… but what if you wanted a bare bones web app – well you’ll have to add user authentication yourself.

That’s where passport comes in really handy. Passport is user authentication middleware which supports a multitude of authentication platforms.

But let’s use it to create a user.

To start with ensure all the relevant dependencies are installed:

$ npm i passport --save
$ npm i passport-local --save
$ npm install bcrypt --save
$ npm i jsonwebtoken --save

With the right dependencies now installed we can generate the User model using

$ sails generate model user

This’ll generate api/models/User.js file . We need to configure the model to include all the user registration fields. I’ve been using Devise in Rails for years so and so used to seeing the standard fields in the model, however let’s keep things simple and just register email_address & password.

Under attributes add the following:

email: {
      type: 'string',
      required: true,
      unique: true
    },
    password: {
      type: 'string',
      required: true
    },
  },

We now need to ensure the password is never returned when querying the User model, so still under attributes add the following:


customToJSON: function() {
return _.omit(this, ['password'])
},

And finally we need to ensure the password is hashed prior to saving it to the database, never store raw passwords in your database – no matter how secure you think it is! We’ll use the bcrypt package we implemented earlier to do this:

beforeCreate: async function(user, cb){
      bcrypt.genSalt(10, function(err, salt){
        bcrypt.hash(user.password, salt, null, function(err, hash){
          if(err) return cb(err);
          user.password = hash;
          return cb();
        });
      });
    }

So that’s the model sorted and if you head to the terminal and into sails console, let’s create a record and retrieve it to test it’s all hooked up OK.

$ sails console

User.create({email: 'user@example.com', password: 'password123'}).log()

If all goes well you should receive a “Finished successfully.” message. To retrieve the user from the database run:

User.find({email: 'user@example.com'}).log()

If you try and add another user with the same email you’ll get an error as we declared that the email is a unique value in the model attributes – it’s good to declare this at a database level also.

Oh, one last thing – ensure you add the following at the top of your model.

const bcrypt = require('bcrypt-nodejs');

Next we’ll move on to the controller