I need to handle persistent session on an Angular app using express and passport on the backend. After a successful login, if I make an http call (using angular $http) to an express API which returns request.isAuthenticated(), it always returns false. This is not case when I login and make the http call to the API using Postman, in that case i got true.
This is my configuration on the server:
server.js
const
express = require('express'),
config = require("../config"),
path = require('path'),
bodyParser = require('body-parser'),
cookiePraser = require('cookie-parser'),
cors = require('cors'),
winston = require("winston"),
morgan = require("morgan"),
mongoose = require("mongoose"),
passport = require("passport"),
session = require("express-session"),
flash = require("connect-flash"),
let app = express(),
server = require("http").Server(app),
io = require("socket.io")(server);
const sessionKey = "mySessionKey";
/*
* ---------------------------------------------------------------------------------------
* app configuration
* ---------------------------------------------------------------------------------------
*/
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.use(morgan("dev"));
app.use(bodyParser.json({limit: "50mb"}));
app.use(cookiePraser(sessionKey));
app.use(express.static("public"));
app.use(session({
secret: sessionKey,
resave: true,
saveUninitialized: true,
cookie: {
secure: false,
httpOnly: false
}
}));
app.use(passport.initialize());
app.use(passport.session());
require("./passportConfig")(passport); // passport configuration
app.get("api/test", function(req, res){
return json({isAuthenticated: req.isAuthenticated()});
})
// [..]
passportConfig.js
const LocalStrategy = require("passport-local").Strategy,
User = require("./models/User");
module.exports = function(passport) {
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function () {
User.findOne({'local.email': email}, function (err, user) {
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
let newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function (err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}
));
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error before anything else
if (err)
return done(err);
// if no user is found, return the message
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
// if the user is found but the password is wrong
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, user);
});
}
));
};
After a login I can see the cookie connect.sid has been set, but then if I try to call "api/test" route using angular $http I get always false (it returns true if I use Postman). Any suggestion on how to fix this?
via revy
No comments:
Post a Comment