Skip to content

Instantly share code, notes, and snippets.

@adityamukho
Last active November 11, 2021 21:41
Show Gist options
  • Save adityamukho/6260759 to your computer and use it in GitHub Desktop.
Save adityamukho/6260759 to your computer and use it in GitHub Desktop.
Passport authentication for Sails.js 0.9.x
/**
* api/services/auth-basic.js
*
* Basic authentication strategy is defined here.
* Other strategies can be defined as needed by adding files like this to the services folder.
*
**/
var passport = require('passport'),
BasicStrategy = require('passport-http').BasicStrategy;
passport.use(new BasicStrategy(function(username, password, next) {
User.findOneByUsername(username).done(function(err, user) {
if (err) {
return next(err);
}
if (!user) {
return next(null, false);
}
user.validPassword(password, function(err, res) {
if (err) {
return next(err);
}
next (null, res ? user : false);
});
});
}));
/**
* api/policies/authenticated.js
*
* This example shows how to use the HTTP Basic authentication strategy using the passport-http module.
* Other strategies (Digest, OAuth, OAuth2, etc) can be similarly implemented.
*
**/
var express = require('express'),
app = express(),
passport = require('passport'),
local = require('../../config/local');
app.use(passport.initialize());
/**
* Allow any authenticated user.
*/
module.exports = function(req, res, ok) {
// User is allowed, proceed to controller
passport.authenticate(local.auth, {session: false}, function(err, user, info) {
if (err || !user) {
return res.send("You are not permitted to perform this action.", 403);
}
return ok();
})(req, res, ok);
};
/**
* config/local.js
*
**/
module.exports = {
port: 1337,
environment: 'development',
adapter: {
mongo: {
module: 'sails-mongo',
host: 'localhost',
// user : 'username',
// password : 'password',
database: 'jscart_dev'
}
},
auth: 'basic' //This is where the authentication strategy to be used is defined.
};
/**
* config/policies.js
*
**/
module.exports.policies = {
// Default policy for all controllers and actions
// (`true` allows public access)
'*': 'authenticated' //define the policy to be used globally, or specific to controllers/actions.
}
/**
* api/models/User.js
*
* The user model contains the instance method for validating the password.
*/
var bcrypt = require('bcrypt');
function hashPassword(values, next) {
bcrypt.hash(values.password, 10, function(err, hash) {
if (err) {
return next(err);
}
values.password = hash;
next();
});
}
module.exports = {
attributes: {
username: {
type: 'STRING',
required: true,
unique: true
},
password: {
type: 'STRING',
required: true,
minLength: 6
},
email: {
type: 'email',
required: true,
unique: true
},
// Override toJSON instance method to remove password value
toJSON: function() {
var obj = this.toObject();
delete obj.password;
return obj;
},
validPassword: function(password, callback) {
var obj = this.toObject();
if (callback) {
//callback (err, res)
return bcrypt.compare(password, obj.password, callback);
}
return bcrypt.compareSync(password, obj.password);
}
},
// Lifecycle Callbacks
beforeCreate: function(values, next) {
hashPassword(values, next);
},
beforeUpdate: function(values, next) {
if (values.password) {
hashPassword(values, next);
}
else {
//IMPORTANT: The following is only needed when a BLANK password param gets submitted through a form. Otherwise, a next() call is enough.
User.findOne(values.id).done(function(err, user) {
if (err) {
next(err);
}
else {
values.password = user.password;
next();
}
});
}
}
};
@adityamukho
Copy link
Author

Rant: I really wish github would enable notifications for comments posted to gists. It's really very easy to miss a new comment if one does not regularly check back on their old gists.

@vijayrajasekaran
Copy link

http://stackoverflow.com/questions/28393254/password-gets-changed-when-updating-user-model-in-sails-js

Can someone help me out? I am using the above code to update User Model. While updating password, it works fine but when i update another field of the user model, the passport again gets encrypted and it is changed while updating. (beforeUpdate)

@winduptoy @adityamukho

@vijayrajasekaran
Copy link

Solution for my above Query:

Now, only if you send password: password in the Update method, it will update the password (hash and store) else it will only update the provided user fields.

Controller(UserController.js):

updateDisplayName: function(req, res) {

var userid = req.token;
var newDisplayName = req.param('newdisplayname');

User.update({id: userid},{displayname: newDisplayName}).exec(function afterwards(err,updated){

if (err) {
res.json(err);
} else {
res.json("Success");
}
});

},

Model(User.js):

beforeUpdate: function(values, next) {
if(values.password) {
hashPassword(values, next);
} else {
next();
}
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment