passport
Simple, unobtrusive authentication for Node.js.
Passport simple, unobtrusive authentication for node.js
Is there a walkthrough tutorial for setting up a simple app with passport local-strategy authentication?
Source: (StackOverflow)
I am writing a nodejs application that I would like to use as both a web application, as well as an API provider. Once a user is authenticated, I want to assign that user a token to be used for subsequent requests. This works great with passport for the web application, as I just serialize and deserialize the user with the token in the session. However, when responding to API requests, there is no cookie to set to store the session information. Ideally, passport would look for the token both in session and the request body. Is there any way to configure passport to accomplish this?
Source: (StackOverflow)
I am having trouble getting my system to log out with PassportJS. It seems the logout route is being called, but its not removing the session. I want it to return 401, if the user is not logged in in specific route. I call authenticateUser to check if user is logged in.
Thanks a lot!
/******* This in index.js *********/
// setup passport for username & passport authentication
adminToolsSetup.setup(passport);
// admin tool login/logout logic
app.post("/adminTool/login",
passport.authenticate('local', {
successRedirect: '/adminTool/index.html',
failureRedirect: '/',
failureFlash: false })
);
app.get('/adminTool/logout', adminToolsSetup.authenticateUser, function(req, res){
console.log("logging out");
console.log(res.user);
req.logout();
res.redirect('/');
});
// ******* This is in adminToolSetup ********
// Setting up user authentication to be using user name and passport as authentication method,
// this function will fetch the user information from the user name, and compare the password for authentication
exports.setup = function(passport) {
setupLocalStrategy(passport);
setupSerialization(passport);
}
function setupLocalStrategy(passport) {
passport.use(new LocalStrategy(
function(username, password, done) {
console.log('validating user login');
dao.retrieveAdminbyName(username, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
// has password then compare password
var hashedPassword = crypto.createHash('md5').update(password).digest("hex");
if (user.adminPassword != hashedPassword) {
console.log('incorrect password');
return done(null, false, { message: 'Incorrect password.' });
}
console.log('user validated');
return done(null, user);
});
}
));
}
function setupSerialization(passport) {
// serialization
passport.serializeUser(function(user, done) {
console.log("serialize user");
done(null, user.adminId);
});
// de-serialization
passport.deserializeUser(function(id, done) {
dao.retrieveUserById(id, function(err, user) {
console.log("de-serialize user");
done(err, user);
});
});
}
// authenticating the user as needed
exports.authenticateUser = function(req, res, next) {
console.log(req.user);
if (!req.user) {
return res.send("401 unauthorized", 401);
}
next();
}
Source: (StackOverflow)
I'm using Express and Passport OpenID Google strategy and I would like to set returnURL on each auth request to be able to return to the page that initiated that auth.
The situation is that I have HTML5 slides application with Node.js backend (and with social stuff and editor and Portal and extensions... https://github.com/bubersson/humla) and I want be able to log in user on some slide (via slide menu...) but then I want him to get back to same slide easily.
So I would need something like this?
app.get('/auth/google', function(req,res) {
var cust = "http://localhost:1338/"+req.params.xxx;
passport.authenticate('google', returnURL:cust, function ...
}
I've read Passport's guide, but still don't know how to do that. I know this wouldn't be safe, but how else could I do it?
Or how can I make the application to return to the page from where the login has been initiated? Or is there a way to make OpenID authentication using AJAX (and still be able to use passport as well)?
Source: (StackOverflow)
I'm using passportJS and I'm wanting to supply more than just req.body.username
and req.body.password
to my authentication strategy (passport-local).
I have 3 form fields: username
, password
, & foo
How do I go about accessing req.body.foo
from my local strategy which looks like:
passport.use(new LocalStrategy(
{usernameField: 'email'},
function(email, password, done) {
User.findOne({ email: email }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Unknown user' });
}
if (password != 1212) {
return done(null, false, { message: 'Invalid password' });
}
console.log('I just wanna see foo! ) + req.body.foo); // this fails!
return done(null, user, aToken);
});
}
));
I'm calling this inside my route (not as route middleware) like so:
app.post('/api/auth', function(req, res, next) {
passport.authenticate('local', {session:false}, function(err, user, token_record) {
if (err) { return next(err) }
res.json({access_token:token_record.access_token});
})(req, res, next);
});
Source: (StackOverflow)
How can I combine passport-local to return a JWT token on successful authentication?
I want to use node-jwt-simple and looking at passport.js I am not sure how to go about.
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
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: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
Is it possible to return the token when calling done() ?
Something like this... (just pseudo code)
if(User.validCredentials(username, password)) {
var token = jwt.encode({username: username}, tokenSecret);
done(null, {token : token}); //is this possible?
}
If not, how can I return the token?
Thank you in advance! :)
/chris
Source: (StackOverflow)
How does one handle authentication (local and Facebook, for example) using passport.js, through a RESTful API instead of through a web interface?
Specific concerns are handling the passing of data from callbacks to a RESTful response (JSON) vs using a typical res.send({ data: req.data }), setting up an initial /login endpoint which redirects to Facebook (/login cannot be accessed via AJAX, because it is not a JSON response - it is a redirect to Facebook with a callback).
I've found https://github.com/halrobertson/test-restify-passport-facebook, but I'm having trouble understanding it.
Furthermore, how does passport.js store the auth credentials? The server (or is it service?) is backed by MongoDB, and I'd expect credentials (login & salted hash of pw) to be stored there, but I don't know if passport.js has this type of capability.
Source: (StackOverflow)
I start planning a REST API with node.js ,express and mongodb. The API provides data for a website (public and private area) and maybe later a mobile app. The frontend will be developed with AngularJS.
For some days I read a lot about securing REST APIs, but I don’t get to a final solution. As far as I understand is to use HTTPS to provide a basic security. But how I can protect the API in that use cases:
Only visitors/users of the website/app are allowed to get data for the public area of the website/app
Only authenticated and authorized users are allowed to get data for private area (and only data, where the user granted permissions)
At the moment I think about to only allow users with a active session to use the API. To authorize the users I will use passport and for permission I need to implement something for myself. All on the top of HTTPS.
Can somebody provide some best practice or experiences? Is there a lack in my “architecture”?
Source: (StackOverflow)
I found a few issues on the main passport repo, however, I think this primarily pertains to this specific strategy as I'm able to successfully authenticate using the passport-google-oauth strategy.
Error: failed to find request token in session
at Strategy.OAuthStrategy.authenticate (/home/glug/application/node_modules/passport-dropbox/node_modules/passport-oauth/lib/passport-oauth/strategies/oauth.js:124:54)
at attempt (/home/glug/application/node_modules/passport/lib/passport/middleware/authenticate.js:243:16)
at Passport.authenticate (/home/glug/application/node_modules/passport/lib/passport/middleware/authenticate.js:244:7)
at callbacks (/home/glug/application/node_modules/express/lib/router/index.js:161:37)
at param (/home/glug/application/node_modules/express/lib/router/index.js:135:11)
at pass (/home/glug/application/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/home/glug/application/node_modules/express/lib/router/index.js:170:5)
at Object.router (/home/glug/application/node_modules/express/lib/router/index.js:33:10)
at Context.next (/home/glug/application/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at Context.actions.pass (/home/glug/application/node_modules/passport/lib/passport/context/http/actions.js:77:8)
I am using redis as the session store, however, even after eliminating that, it's still failing with the identical error message.
var DropboxStrategy = require('passport-dropbox').Strategy;
app.configure(function(){
app.set('port', config.express.port);
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({
// store: new RedisStore({ client: redis}),
secret: config.express.secret
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
});
passport.serializeUser(function(user, done) {
// console.log('Serializing: ' + JSON.stringify(user));
done(null, user);
});
passport.deserializeUser(function(obj, done) {
// console.log('Deserializing: ' + obj);
done(null, obj);
});
passport.use(new DropboxStrategy({
consumerKey: config.dropbox.key,
consumerSecret: config.dropbox.secret,
callbackURL: config.dropbox.callbackURL
},
function(token, tokenSecret, profile, done) {
// My storage function
return done(null, profile);
}
));
I'm happy to try anything, I've filed an issue on the repo, but I think it may be something I'm doing wrong rather than something wrong with the passport-dropbox repo.
Source: (StackOverflow)
This error occurs on Heroku (production) only, not on local.
I have tried both:
passport.authenticate('google', { scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/analytics.readonly' })
And,
passport.authenticate('google', { scope: ['profile', 'email'] })
Whether the scope is an array, or a space-delimited string.
When I go to the Google authentication link, scope IS in the URL. There is no difference in the one generated in my live production app.
But I still get:
Error 400
Error: invalid_request
Missing required parameter: scope
Source: (StackOverflow)
I would like to use passport.js to verify that when users hit certain endpoints that they not only have the correct password but are a member of a specific group or have a certain access.
For simplicity sake if I have access levels of USER and ADMIN.
I can use passport to authenticate a password:
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: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
Then with a route I can make sure the user passes auth:
app.get('/api/users',
passport.authenticate('local'),
function(req, res) {
res.json({ ... });
});
But lets say you need to have ADMIN acess to hit /api/users'. Do I need to write my own Strategies? IE do I need to have a local-user, and local-admin strategy, and in each verify the proper access levels?
I think I can do this pretty easily, but the problem arises when I need my site to have different auth methods (maybe sometimes use oauth), I would need to write custom *-user, *-admin strategies for each. Seems like overkill.
Other option is to just verify access/group in each route after the user has been authenticated. But I would prefer to do this in the middle-ware if possible.
Thanks
Source: (StackOverflow)
I am using pssportjs with express 2.x and a sessions storage. After a login I am getting req.User only once. As soon as I redirect again req.User is undefined.
Here is my config:
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(userId, done) {
User.findOne({_id: userId} ,function(err, user){
done(err, user);
});
});
// Authentication Strategy
passport.use(new FacebookStrategy({
clientID: CONFIG.fb.appId,
clientSecret: CONFIG.fb.appSecret,
callbackURL: CONFIG.fb.callbackURL
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
User.findOne({ 'accounts.uid': profile.id, 'accounts.provider': 'facebook' }, function(err, olduser) {
if(olduser) {
done(null, olduser);
} else {
var newuser = new User();
var account = {provider: "facebook", uid: profile.id};
newuser.accounts.push(account);
newuser.firstname = profile.name.givenName;
newuser.lastname = profile.name.familyName;
newuser.email = "TBD...";
newuser.save(function(err) {
if(err) { throw err; }
done(null, newuser);
});
}
});
});
}
));
var app = module.exports = express.createServer();
// configure express
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.compiler({ src : __dirname + '/public', enable: ['less']}));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
//app.use(express.session({ secret: "keyboard cat" }));
app.use(express.session({
secret: "victory cat",
store: new MongoStore({
url: CONFIG.dbMongo.url
})
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
These are my routes:
app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['user_status', 'user_photos'] }));
app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/index', failureRedirect: '/' }));
app.get('/index', function(req, res) {
res.render('index.ejs', {
siteTitle: "Welcome",
siteUrl: CONFIG.server.siteUrl,
user: req.user
});
});
And finally this is how I am trying to access the user object in my view:
<div class="page-header">
<h3><%= siteTitle %></h3>
</div>
<% if (!user) { %>
<p>Not logged in !</p>
<% } else { %>
<p>Hello, <%= user.firstname %> <%= user.lastname %>.</p>
<% } %>
After authenticating with facebook my view displays firstname and lastname correctly. After another page request req.User is undefiend (deserializing is not being invoced).
What am I doing wrong?
Source: (StackOverflow)
Using Nodejs Passport, I was testing out what happens when an error condition occurs using the following code:
passport.use(new LocalStrategy(
function(username, password, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
findByUsername(username, function(err, user) {
console.log('in auth function');
return done('errortest');
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Unknown user ' + username });
}
if (user.password != password) {
return done(null, false, { message: 'Invalid password' });
}
return done(null, user);
})
});
}
));
app.get('/logintest', function(req, res, next) {
console.log('before authenticate');
passport.authenticate('local', function(err, user, info) {
console.log('authenticate callback');
if (err) { return res.send({'status':'err','message':err.message}); }
if (!user) { return res.send({'status':'fail','message':info.message}); }
req.logIn(user, function(err) {
if (err) { return res.send({'status':'err','message':err.message}); }
return res.send({'status':'ok'});
});
})(req, res, next);
});
Using the route /logintest?username=bob&password=s I expected to see in the console, "before authenticate" then "in auth function" then "authenticate callback" but it only shows the first two followed by "errortest", and "errortest" is displayed in the browser.
I also tried return done({'message':'test'});
and "[object Object]" was displayed in the console and in the browser.
Is this not working properly or am I missing something?
EDIT: As per Jared Hanson's response, adding this error handler function as the third argument to app.get() allows me to catch the error and return the appropriate json:
...
})(req, res, next);
},
function(err, req, res, next) {
// failure in login test route
return res.send({'status':'err','message':err.message});
});
Source: (StackOverflow)
I'm using Node.js and intend to use Passport for authentication. However, all of the examples I see online assume the user has already been created. I'd like to know how to create a user's session correctly, after they are saved in the database (I have this part working), so that Passport will recognize them. (I do not want to save the new user and then force them to go to a login page.)
Source: (StackOverflow)