[英]express session and passport: req.isAuthenticated() return false after login
I need to handle persistent session on an Angular app using express and passport on the backend. 我需要在后端使用快递和护照处理Angular应用程序上的持久会话。 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. 成功登录后,如果我对返回request.isAuthenticated()的快速API进行http调用(使用angular $ http ),它将始终返回false。 This is not case when I login and make the http call to the API using Postman, in that case i got true. 当我登录并使用Postman对API进行http调用时,情况并非如此,在这种情况下,我得到了真的。
This is my configuration on the server: 这是我在服务器上的配置:
server.js 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 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);
});
}
));
};
loginService.js (expose function for login): loginService.js(公开登录功能):
this.login = function(email, password) {
return new Promise((resolve, reject) => {
$http({
url: serverBaseURL + "/api/login",
method: "POST",
`enter code here` data: JSON.stringify({
email: email,
password: password
}),
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
}
}).then(function (response) {
resolve(response);
}, function (errorResponse) {
reject(errorResponse);
});
});
};
In the controller I perform the login and then I make another http call to check if I am really logged in: 在控制器中我执行登录,然后我再次进行http调用以检查我是否真的登录:
loginCtrl.js loginCtrl.js
loginService.login($scope.email, $scope.password).then(response => {
if (response.status === 200) {
// check if I am really logged in, include the connect.sid cookie in the call => withCredentials = true
$http({
url: serverBaseURL + "/api/test",
method: "GET",
headers: {
"Accept": "application/json"
},
withCredentials: true,
}).then(function (response) {
console.log(response); // I always get false in the response
}, function (errorResponse) {
console.log(errorResponse);
});
}
}, error => {
// handle error
});
// [..]
I've noticed two things: 我注意到两件事:
Any idea what am I missing? 知道我错过了什么吗?
我发现了这个问题,因为我有同样的情况,总是从request.isAuthenticated()和状态401得到假。解决方案是@Mukesh Sharma写的是不要忘记在客户端前端添加:
{ withCredentials: true }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.