-
-
Save adityamukho/6260759 to your computer and use it in GitHub Desktop.
/** | |
* 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(); | |
} | |
}); | |
} | |
} | |
}; |
And if you need use the current user in other policy or in your app... how you can retrieve or use?
HTTP Basic authentication does not use sessions, so if the current user needs to be retrieved in another part of the application, it can be done by storing the user object in a req
attribute (in authenticated.js
). This example does not demonstrate that use case, but it should be easy to implement, by adding the code to the exported middleware.
Thank you very much, I think also that req.yourattribute is the best place :)
With sails 0.9.x do not work. helpme please.
My first suggestion would be to check if you're still actually on sails 0.9.x. If you have updated recently, you could be running 0.10.x, which has introduced several changes that will break this gist.
Once you've verified you're on the correct version, I'll need to see the errors/stacktraces in order to figure out what went wrong.
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.
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
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();
}
},
authentication is done by sending HTTP basic authentication headers with each request. See http://en.wikipedia.org/wiki/Basic_access_authentication for more details.