jaredhanson / passport-local Goto Github PK
View Code? Open in Web Editor NEWUsername and password authentication strategy for Passport and Node.js.
License: MIT License
Username and password authentication strategy for Passport and Node.js.
License: MIT License
Hello there,
first of all nice work done here thanks for that.
I've read today the first time about PassportJS and wanted to test out the local approach with users stored in a MongoDB document.
Ultimately of course my naming convention for the properties was different then the default for passport-local. So it took me some time to find the hint about passing an options-parameter so that I can map my fieldnames
I'd propose to add that information to the Repo README and maybe also adapt the examples to help newcomers get up and running faster.
Hi everyone i try to connect mysql db to authenticate the user through passport.js, i do not whats wrong in my code. when i gave correct or wrong user and password information it takes me failureredirect. Can anyone tell me whats wrong in that. i am new to this.
here is my code:
var flash = require('connect-flash');
var express = require('express');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(function(username,password,done){
connection.query("select * from userinfo where UserName='"+username+"' ",function(err,user){
if(err)
{
return done(err);
}
if(!user)
{
return done(null,false,{message: 'Incorrect user name'});
}
if(user.password != password)
{
return done(null,false,{message: 'Incorrect password'});
}
return done(null,user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
app.post('/validates', passport.authenticate('local',{successRedirect: '/productdisplay', failureRedirect: '/validate', failureFlash: true }));
and also flash message is not working. Please tell me almost i spent much time in this and i am not get any error.i dont know how to solve this.
Can we just do this?
this._passReqToCallback = options.passReqToCallback || verify.length == 4;
Greetings,
I've been trying to get passport to authenticate a user via Twitter, but return them to the protected resource that triggered the authentication request in the first place. I'm failing to make this work, sadly. It would be very useful if some of the documentation would make it clear how to achieve this. I'll even volunteer to update the documentation if someone could tell me how this is done.
Thanks.
From the piece of the code that was given for an example in passportjs documentation
passport.use(new LocalStrategy(
function(username, password, done) {
I finally realise that PassportJS try to automatically get the username / password field in the post request automatically but the problem is that I am using angularjs and ajax to do the submission so my post request for the login would be just a json object contains information scraped from the login form. Is there any option to manually pass the username and password directly as variable ?
I think the software sounds great but the documentation is abysmal.
I would like to see a simple, minimalist and most importantly, complete how-to. This should not be a link to code on github. This should be a single file app which is liberally interspersed with codes and shows how to integrate passportjs with expressjs.
I have searched there's a lot of tidbits floating around but not a single cohesive example that I could find.
It might also help to illustrate the 2 or 3 most common strategies this way. My personal choice would be Local, Google and Facebook.
Thank you so much for making this. It's wonderful! Can you please include a sign up page in your examples? I've got the login working. I'd like to let people sign up by entering an email address and password. Thanks!
I'm attempting to move from a local redis server to Iris Redis. When I login using the local redis server, the session is created and the user authenticates.
However, when using the remote store, I'm redirected back to the login page despite my passport local strategy passing.
I'm assuming this is a session issue. Could it have anything to do with cross domains if I'm using a remote redis server on localhost?
Would love some documentation on the ensureAuthenticated function and how it works. I have the same code in my Express app but it doesn't seem to work. Instead, it returns that it cannot GET /admin, which is the route that I am trying to ensure authentication.
How can i access the post data from the signup-form?
For example I will add a sur and a prename to the users profile:
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
newUser.local.prename = prename; //how can i get it from my form?
newUser.local.surname = surname;
newUser.role = false;
newUser.activated = false;
"As of express 3.4.0 (connect 2.9.0) bodyParser is deprecated. It goes without saying that deprecated things should be avoided." [1]
Does this fact affect passport-local? I ran across this issue because I'm currently trying to login by sending json in the body via angular/restangular, ie:
{
email: "[email protected]"
password: "appleseed"
}
Which makes the question a two-fer... How do I remove bodyParser()
and get passport to look for my json body instead of form-data body?
[1] http://andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html
i'll try to code something for a 'remember me' checkbox. With it, i'll be able to restore a session with cookie saved in the client browser.
if 'remember me' is checked in the webpage when loggin, the node app on the server creates two cookies : id and token with an expiration date of Today + 30 days. Token is something random and long like 40 char. It is stored in database with NOW date/time. (It could be great to reuse connect.sid but don't know how without messing deep into connect code)
Then in the node app in ensureAuthenticated function,
I have to modify it, so if session is dead, check if cookie 'id' & 'token' were sent and have a look in database to check if the couple id,token is in db.
If yes, delete the entry id,token,date in db and insert a new one generated. Also every 30 days, delete too old 'id,token' from db.
Also, create a cookie named 'weak' because this cookie authentification is weaker than a real login with 'id,password'. So if in the backend there are some unsafe operations for the user like 'delete account' or something about money, you have to ask the user a stronger authentification with the password.
All this is based on security stuffs i've read on StackOverflow (cookie stealing ...) but I would be pleased to know if I'm going right/wrong, advices, and why it hasn't been done, maybe because i'm wrong ...
Thank you
Line 82 of strategy.js does this:
if (!user) { return self.fail(info); }
The method signature for 'fail' however is:
actions.fail = function(challenge, status) {
As a result passport-local is unable to set challenge and error status codes on the reply.
For some reason, calling req.logout()
does not remove session, and so is delete req.user
.
I'm using Express 2.5.9, Passport 0.1.8 and Passport-local 0.1.2.
package.json:
"passport" : "*",
"passport-local" : "*",
"connect-flash" : "*",
"bcrypt-nodejs" : "*"
app.js
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
var session = require('express-session')
var flash = require('connect-flash');
app.use(cookieParser());
app.use(session({ secret: 'okthxbye', key: 'user', cookie: { maxAge: 60000, secure: false }}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
/config/passport.js
passport.serializeUser(function(user, done) {
done(null, user.email);
});
passport.deserializeUser(function(email, done) {
var db = req.db;
var collection = db.get('users');
collection.find({
'email': email
}, {}, function(err, user) {
if (err)
return done(err);
done(err, user);
});
});
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
var db = req.db;
var collection = db.get('users');
collection.findOne({ 'email' : email }, {}, function(err, user) {
if (err)
return done(err);
if (!user)
return done(null, false, req.flash('loginMessage', User not found.'));
if (validPassword(password, user.password))
return done(null, false, req.flash('loginMessage', 'Wrong password.'));
return done(null, user);
});
}));
routes/index.js
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/',
failureRedirect : '/login',
failureFlash : true
}));
app.get('/', function(req, res) {
res.render('index.html', {});
});
request
POST http://localhost:3000/login
Header: Content-type: application/json
Body: {"email": "[email protected]", "password":"123"}
The screenshot above show the redirect to index.html (after login success) and then suddenly redirect to login.html again.
What I need to do?
Thanks!
In case of xhr requests, is there any way to send response in json format with http status code? currently the only options are to redirect...
passport.authenticate('local', {
failureFlash: 'Invalid email or password.',
failureRedirect: '/'
})
The basic & digest strategies complies with the RFC 2617 spec (http://passportjs.org/guide/basic-digest/).
Does passport-local complies to any RFC specs? If so it would be great to have it mentioned in the README page...
After installing the files into a folder, running "npm install" and then running "node app.js" from the command line I get the following error:
C:\Users\lfernandez\Documents\folders\node\login>node app.js
C:\Users\lfernandez\Documents\folders\node\login\app.js:79
app.configure(function() {
^
TypeError: Object function (req, res, next) {
app.handle(req, res, next);
} has no method 'configure'
at Object. (C:\Users\lfernandez\Documents\folders\node\login\app.
js:79:5)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:902:3
When you add node cluster feature to a project it will redirect to login page every time. I don't know too much detail of passport-local, but if anything is being held in memory server side for the node process then obviously it breaks with clustering multi process features.
Hi,
I tried the passport-local-mongoose example and it worked perfectly in one file. I added a signup form and separated the passport code to passport.js and User model to models/user.js. Since then passport.authenticate by login and req.Login() by signup return the first user in the db no matter which (existing) user I input. I can't figure out why, here is my code and thanks for any help! Trang
models/user.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
bcrypt = require('bcrypt'),
SALT_WORK_FACTOR = 10;
// UserSchema
var UserSchema = new Schema({
username: { type: String, required: true, index: { unique: true } },
password: { type: String, required: true }
});
UserSchema.pre('save', function(next) {
var user = this;
if (!user.isModified('password')) return next();
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
UserSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if(err) return cb(err);
cb(null, isMatch);
});
};
module.exports = mongoose.model('User', UserSchema);
passport.js
var mongoose = require('mongoose')
, User = mongoose.model('User')
, passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
module.exports = function(passport){
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findOne(id, function (err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy(function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Unknown user ' + username });
}
user.comparePassword(password, function(err, isMatch) {
if (err) return done(err);
if(isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Invalid password' });
}
});
});
}));
};
app.js
var express = require('express')
, http = require('http')
, path = require('path')
, fs = require('fs')
, passport = require('passport')
, mongoose = require('mongoose')
, mongoStore = require('connect-mongo')(express);
// Connect mongoose
mongoose.connect('mongodb://localhost/upload');
//Bootstrap models
var models_path = __dirname + '/models';
fs.readdirSync(models_path).forEach(function (file) {
require(models_path+'/'+file)
});
var app = express();
//configure Express
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.locals.pretty = true;
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
secret:'lolcat',
maxAge: new Date(Date.now() + 3600000),
store: new mongoStore({
url: 'mongodb://localhost/upload'
})
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Bootstrap passport
require('./passport')(passport);
app.get('/', function(req, res){
res.render('index', { user: req.user });
});
app.get('/account/:username', ensureAuthenticated, function(req, res){
if (req.params.username=== req.user.username){
res.render('users/account', { user: req.user });
}
else res.redirect('/');
});
//show login and signup forms
app.get('/login', function(req, res){
res.render('users/login', { pageTitle: 'Log In', user: req.user});
});
app.get('/signup', function(req, res){
res.render('users/signup', { pageTitle: 'Sign Up', user: req.user});
});
//handle submit post from signup and login forms
app.post('/signup', function (req, res) {
var user = new User(req.body);
user.provider = 'local';
user.save(function (err) {
if (err) {
return res.render('users/signup',
{pageTitle: 'Sign up',
errors: err.errors,
user: user }); }
req.logIn(user, function(err) {
if (err) return next(err);
return res.redirect('/');
});
});
});
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) {
return res.redirect('/login');
}
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/');
});
})(req, res, next);
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
Hi,
Currently the 'Missing credentials' (BadRequestError) also gets thrown on empty username or password instead of only 'undefined' username or password. This results in a thrown error on an empty login form submit (with a fixed message in a language my application doesnt support).
Why not only throw on actually missing username or password fields in the body? And pass them along to the 'verify' even if empty and let the verify call handle the check (which will not find anything, since the username/password are empty) and return a proper error message (which can than be in any language I want).
Regards,
Wytze
Should we implement this as a default or leave it up to the users of passport-local
?
https://github.com/jaredhanson/passport-local/blob/master/lib/passport-local/strategy.js#L70
Hi,
I've got the latest version of Express.js (3.1) and Node.js (0.10). I've integrated Passport.js with the Local Strategy. Everything seems to work well apart from when I am logged in I cannot do post requests anymore. Nothing happens.
Any idea what I might be doing wrong?
Thanks.
I'm new to passport and just ran the login example on my local machine.
When I log in as 'bob', password.serializeUser and password.deserializeUser are called.
Thats fine, but why is password.deserializeUser called two times?
How can I cache the user, so I don't have pull him from the db every time password.deserializeUser is called.
When my login form is built, the username/password forms are named user[username]
and user[password]
as per the following:
<input type="text" name="user[username]" id="user_username"/>
<input type="password" name="user[password]" id="user_password"/>
As such, I need my local passport config to appear as follows:
app.post('/login', passport.authenticate('local', {
usernameField: 'user[username]',
passwordField: 'user[password]'
}));
Unfortunately, this setup doesn't work. I assume it's because Express converts user[username]
and user[password]
into an object such that the request body is represented as {user: {username: "foo", password: "bar"}}
, and passport-local is attempting to look up the exact request body keys provided.
Use case:
User opened page. Leave it open for a while. Refresh page. Gets redirected to login
page.
I want to redirect user to the page where he was before after successful login.
Hi Jared.
I would like to know if there is some way to move authentication form to a different subdomain.
When user tries to access restricted area he is redirected to auth. subdomain and asked to enter username, password. When done he is redirected back to where he wanted.
When doing a "local" verify call I need more information than just the username and password. By default I don't see a way to pass extra data to the verify function. Would you take patches? What would be the "passportjs-style" of doing it?
Is there any plan to implement password-reset/ account retrieval with passport-local?
Thanks, Trang
If I run my app from azure websites (or locally), the hashing process is fine but when I run the app from an ubuntu server the hash ends up being an array of numbers and doesn't match when I login next time. As example of the generated hash is:
[131, 207, 39, 149, 218, 216, 190, 147, 126, 136, 60, 13, 250, 255, 181, 206, 15, 52, 236, 144, 113, 188, 185, 113, 74, 169, 30, 189, 137, 185, 154, 188, 101, 131, 115, 175, 194, 90, 122, 13, 58, 131, 222, 146, 0, 138, 237, 225, 105, 162, 208, 110, 31, 174, 92, 143, 230, 95, 11, 145, 26, 29, 210, 177, 220, 144, 1, 218, 240, 97, 97, 153, 157, 26, 109, 127, 137, 90, 101, 105, 7, 20, 162, 22, 66, 199, 153, 168, 64, 52, 218, 138, 221, 199, 27, 167, 206, 167, 182, 129, 137, 173, 127, 36, 180, 82, 121, 181, 53]
This has basically put a complete blocker on my whole app. Any ideas?
npm install report. i am not sure this is bug for this npm. please give a check.
Rather than asking the app if the request parameter should be added to the front of the verify callback function arguments, it should be added to the end of every verify callback, therefore making it optional but available to all requests, and not affecting the order of arguments for that callback.
Hi if a login fails. Is there any possibility to get the user name after the redirect?
What is the point of accessToken / generateRandomToken() ?
Comments suggest that it is used for Remember Me implementation, while it isn't. The only thing req.body.rememberme handling middleware changes/uses is session cookie expiration.
The code uses accessToken as a unique identifier (while it isn't marked unique in schema - only enforced by code) to serialize/deserialize user to/from session.
Looking at express3-mongoose-rememberme/app.js line 18, you find that there are already two unique identifiers for a User: username and email, which could be used to deserialize user.
There is no need to implement such convoluted code in something supposed to be an example.
Hi Jared!
I'm using passport for multiple account authentication (facebook, twitter, etc.) so I have multiple modules for authenticating different accounts. Here's an example of facebook authentication.
I've added printSomething function to show that passport.authenticate() is not calling next().
And when I try to login with facebook I get this kind of output:
Express server listening on port 8000
Connected to database
GET / 302 8ms - 68
GET /login 200 54ms - 266
GET /auth/facebook 302 46ms - 590
I'm still here
I'm still here
..... aaand that's all, /auth/facebook/callback pending forever..
The odd thing is that no errors raised and that's very frustrating.
Everything was working fine, btw until today.
module.exports = function(app, passport) {
var config = app.get('config');
var initFacebookStrategy = function(req, res, next) {
var FacebookStrategy = require('passport-facebook').Strategy;
passport.use(new FacebookStrategy({
clientID: config.social.facebook.key,
clientSecret: config.social.facebook.secret,
callbackURL: config.app.url + "auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
var Member = app.get('importer').model('member');
app.set('FACEBOOK_ACCESS_TOKEN', accessToken);
var member = new Member(Member.facebookProfileToMemberJSON(profile));
member.authorize(req, res, function(member) {
return done(null, member);
})
}
));
return next();
}
var printSometing = function(req, res, next) {
console.log("I'm still here");
return next();
}
// GET /auth/facebook/callback
// Use passport.authenticate() as route middleware to authenticate the
// request. If authentication fails, the user will be redirected back to the
// login page. Otherwise, the primary route function function will be called,
// which, in this example, will redirect the user to the home page.
app.get('/auth/facebook/callback', printSometing, initFacebookStrategy, printSometing,
passport.authenticate('facebook', { failureRedirect: '/login' }), printSometing,
function(req, res) {
if (req.session.redirectURL) {
var redirectURL = req.session.redirectURL;
req.session.redirectURL = null;
res.redirect(redirectURL)
} else res.redirect('/');
});
// GET /auth/facebook
// Use passport.authenticate() as route middleware to authenticate the
// request. The first step in Facebook authentication will involve
// redirecting the user to facebook.com. After authorization, Facebook will
// redirect the user back to this application at /auth/facebook/callback
app.get('/auth/facebook', initFacebookStrategy,
passport.authenticate('facebook', { scope: config.social.facebook.scope }));
}
Hello,
After I create a user, I want to automatically log him into sessions and then redirect him to a page. How can I do that via code?
app.post('/register', function(req, res){
registerUser(req.body, function(created_user){
//LOG IN created_user , how?
res.redirect('/home');
});
});
I'm using the standard example for regular login (not via code).
In 'express3-mongoose-multiple-files' example, I see the error message after run 'adduser' grunt task:
Error: ValidationError: Validator "required" failed for path password, Validator "required" failed for path email, Validator "required" failed for path username
It's a bug or similar? How I add user with grunt task?
Wouldn't it be a good idea to show how to properly hash passwords in the example? Somebody might otherwise get the idea of just copying it, storing plaintext passwords in their database.
jake aborted.
undefined
after running:
passport-local\examples\express3-mongoose-multiple-files\db>jake -f seed.js seed
drop.js ran fine
Hi Jared,
I need to render a form on login failure showing an error. What is the most elegant way to do that with password?
Just wondering if support could be added for passing an object to the verified()
function?
function verified(err, user, info) {
return (typeof(err) === 'object') ? self.error(JSON.stringify(err)) : self.error(err);
if (!user) { return self.fail(info); }
self.success(user, info);
}
This simple solution would allow for the following in the authenticate()
function
authenticate: function(username, pw, done) {
User.findByName(username, function(err, user) {
if (err) { return done(err); }
if (!user) { return done({ error: 'Unknown user ' + username }, false); }
if (!User.checkPassword(pw, user)) { return done({ error: 'Invalid password' }, false); }
return done(null, user);
});
},
This would allow a more descriptive error message to be displayed, rather than just a true/false.
Thoughts?
Hi there,
you are using the process.nextTick()
function in the example code which already caused problems in other passport-strategies. I had to remove this function in the code to make everything properly, because the code would ran always asynchronously in a way where passport gets confused.
I do not know why this is still used in so many examples, and I am interested why it breaks passports process.
As per my discussion with Jared via IM, this issue is to require the ability to pass back authentication failure messages to the passport.authenticate function. Perhaps via:
passport.authenticate(... func(err, user, info))
The issue right now is that there is no good way to return back an error message from the LocalStrategy. The only option is to either return a server failure via 'err' which will cause the server to simply return a 500 HTTP error, or to use a workaround which uses the user object to return back the error message.
As a result, the done function will probably look something more like this:
done(null, false, 'bad password')
Here is a jsfiddle where I'm running into the issue. In this example, the server simply returns a 500 error for all failures -- and I want it to return an error string instead:
i try app sample remember me, it doesn't work at all. After closing browser i have to sign in again.
var express = require('express')
, passport = require('passport')
, LocalStrategy = require('passport-local').Strategy
, mongodb = require('mongodb')
, mongoose = require('mongoose')
, bcrypt = require('bcrypt')
, SALT_WORK_FACTOR = 10
, RedisStore = require('connect-redis')(express);
mongoose.connect('localhost', 'test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback() {
console.log('Connected to DB');
});
// User Schema
var userSchema = mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true},
accessToken: { type: String } // Used for Remember Me
});
// Bcrypt middleware
userSchema.pre('save', function(next) {
var user = this;
if(!user.isModified('password')) return next();
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if(err) return next(err);
bcrypt.hash(user.password, salt, function(err, hash) {
if(err) return next(err);
user.password = hash;
next();
});
});
});
// Password verification
userSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if(err) return cb(err);
cb(null, isMatch);
});
};
// Remember Me implementation helper method
userSchema.methods.generateRandomToken = function () {
var user = this,
chars = "!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
token = new Date().getTime() + '';
for ( var x = 0; x < 16; x++ ) {
var i = Math.floor( Math.random() * 62 );
token += chars.charAt( i );
}
return token;
};
// Seed a user
var User = mongoose.model('User', userSchema);
var usr = new User({ username: 'bob', email: '[email protected]', password: 'secret' });
usr.save(function(err) {
if(err) {
console.log(err);
} else {
console.log('user: ' + usr.username + " saved.");
}
});
// Passport session setup.
// To support persistent login sessions, Passport needs to be able to
// serialize users into and deserialize users out of the session. Typically,
// this will be as simple as storing the user ID when serializing, and finding
// the user by ID when deserializing.
//
// Both serializer and deserializer edited for Remember Me functionality
passport.serializeUser(function(user, done) {
var createAccessToken = function () {
var token = user.generateRandomToken();
User.findOne( { accessToken: token }, function (err, existingUser) {
if (err) { return done( err ); }
if (existingUser) {
createAccessToken(); // Run the function again - the token has to be unique!
} else {
user.set('accessToken', token);
user.save( function (err) {
if (err) return done(err);
return done(null, user.get('accessToken'));
})
}
});
};
if ( user._id ) {
createAccessToken();
}
});
passport.deserializeUser(function(token, done) {
User.findOne( {accessToken: token } , function (err, user) {
done(err, user);
});
});
// Use the LocalStrategy within Passport.
// Strategies in passport require a verify
function, which accept
// credentials (in this case, a username and password), and invoke a callback
// with a user object. In the real world, this would query a database;
// however, in this example we are using a baked-in set of users.
passport.use(new LocalStrategy(function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
user.comparePassword(password, function(err, isMatch) {
if (err) return done(err);
if(isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Invalid password' });
}
});
});
}));
var app = express();
// configure Express
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('ejs', require('ejs-locals'));
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({
store: new RedisStore({ host: '127.0.0.1', port: 6379, prefix: 'chs-sess' }),
secret: '4Md97L1bL4r42SPn7076j1FwZvAiqube',
maxAge: new Date(Date.now() + 3600000)
}));
// Remember Me middleware
app.use( function (req, res, next) {
if ( req.method == 'POST' && req.url == '/login' ) {
if ( req.body.rememberme ) {
req.session.cookie.maxAge = 2592000000; // 30_24_60_60_1000 Rememeber 'me' for 30 days
} else {
req.session.cookie.expires = false;
}
}
next();
});
// Initialize Passport! Also use passport.session() middleware, to support
// persistent login sessions (recommended).
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(__dirname + '/../../public'));
});
app.get('/', function(req, res){
res.render('index', { user: req.user });
});
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
app.get('/login', function(req, res){
res.render('login', { user: req.user, message: req.session.messages });
});
// POST /login
// Use passport.authenticate() as route middleware to authenticate the
// request. If authentication fails, the user will be redirected back to the
// login page. Otherwise, the primary route function function will be called,
// which, in this example, will redirect the user to the home page.
//
// curl -v -d "username=bob&password=secret" http://127.0.0.1:3000/login
//
/***** This version has a problem with flash messages
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
function(req, res) {
res.redirect('/');
});
*/
// POST /login
// This is an alternative implementation that uses a custom callback to
// acheive the same functionality.
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err) }
if (!user) {
req.session.messages = [info.message];
return res.redirect('/login')
}
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/');
});
})(req, res, next);
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
app.listen(3000, function() {
console.log('Express server listening on port 3000');
});
// Simple route middleware to ensure user is authenticated.
// Use this route middleware on any resource that needs to be protected. If
// the request is authenticated (typically via a persistent login session),
// the request will proceed. Otherwise, the user will be redirected to the
// login page.
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
Getting an error when running jake -f db/seed.js
jake aborted.
Error: Unknown task "default"
at TaskBase.nextPrereq (/usr/local/lib/node_modules/jake/lib/task/task.js:158:19)
(See full trace by running task with --trace)
Any idea why it happens?
I posted this on stackoverflow:
http://stackoverflow.com/questions/12217881/nodejs-passport-authenticate-callback-not-being-called
Is this a bug?
It would be helpful if someone could add an example showing how to update/change a users password using the bcrypt module.
I use restify as the server and use passport and passport-local to do authentication with username and password. However I always get 401 response. I checked the payroll, it is correct. Then I checked passport-local, it is incompatible with restify when using post method.
Here is the problem in passport-local / strategy.js line 92
in function lookup(), the req.body passed in from restify is a string, not an object. So when passing the parameters in post body, it goes wrong.
Hi, I am trying to use Password (using Consumer, Token and Local) in a API (using Swagger.js). I have been able to define attach different strategies to different paths depending upon the level of auth needed.
THIS: if (!layer) { return allFailed(); }
I have found the allFailed() returns a 401 Unauthorized - Is there a best practice for letting the app handle this? For example when the local auth fails, I would like to return 401 one of the following:
I realized that the expected usage is for an express app.
Thanks,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.