Git Product home page Git Product logo

passport-local's People

Contributors

andr3w321 avatar atupal avatar bobzoller avatar elmakras avatar fmalk avatar hemslo avatar jaredhanson avatar jaykan avatar mhuggins avatar nicrizzo avatar pdehaan avatar techplexengineer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

passport-local's Issues

Add info in README/Examples about Strategy-Options-Parameter

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.

With My SQL

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.

Document how to return newly authenticated to originally requested resource

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.

Manually input variable for credentials instead of using a form

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 ?

A Simple, Minimalist, Complete How-to

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.

Registration

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!

Can't authenticate Express app using remote Iris Redis server

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?

ensureAuthenticated Middleware not working

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.

Add extra field to login form

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;

bodyParser

"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

feature request : 'remember me' checkbox, cookies to resume session

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

Incorrect call to self.fail in strategy::authenticate

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.

Can't logout anymore

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.

isAuthenticated() false after login using Express 4

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"}

requests

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!

allow xhr response

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: '/' 
})

Error when running example

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

passport.authenticate return the first signed-up user

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')
}

Only throw 'Missing credentials' if actually missing

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

Post requests after authentication not working

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.

passport.deserializeUser called multiple times

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.

usernameField & passwordField do not work with array of params

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.

Redirect after successful login

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.

Authentication on different subdomain

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.

Allow extra parameters to local verify call

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?

Hash not working properly from ubuntu

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?

passReqToCallback should be removed

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.

Misleading code in express3-mongoose-rememberme example

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.

passport.authenticate() does nothing on callback.

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 }));


}

How to manually log a user in?

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).

Error of running "adduser" grunt task

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?

Password hashing

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 and undefined

jake aborted.
undefined

after running:
passport-local\examples\express3-mongoose-multiple-files\db>jake -f seed.js seed

drop.js ran fine

How to render form on failure

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?

Allow object to be shown in error callback

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?

Old code

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.

Allow passport to return authentication failure messages via variable

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:

http://jsfiddle.net/nd8LZ/1/

Remember me doens't work at all

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')
}

Jake aborted for express3-mongoose-multiple-files

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?

Can not work with restify when posting parameters

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.

Possible to Delegate AllFailed() to App?

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:

  1. { message: 'missing username' },
  2. { message: 'missing password' }
    etc.

I realized that the expected usage is for an express app.

Thanks,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.