我是Angular.js的新手并尝试为网站构建本地身份验证。我已经浏览了各种来源,Authentication in Single Page Applications非常有帮助。当我尝试在我的localhost中构建相同的代码时,我的代码进入循环。
app.post('/login',.....)
在响应中返回用户,但在加载管理页面之后,它正在通过调用app.get('/loggedin',... )
来检查用户是否已登录,并且req.isAuthenticated()
正在返回{{1}即使在登录后它进入循环。我无法理解为什么会这样,请帮助我。
服务器端代码
false
客户端Js文件
var express = require('express');
var http = require('http');
var path = require('path');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
//==================================================================
// Define the strategy to be used by PassportJS
passport.use(new LocalStrategy(
function(username, password, done) {
if (username === "admin" && password === "admin") // stupid example
return done(null, {name: "admin"});
return done(null, false, { message: 'Incorrect username.' });
}
));
// Serialized and deserialized methods when got from session
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
// Define a middleware function to be used for every secured routes
var auth = function(req, res, next){
if (!req.isAuthenticated())
res.send(401);
else
next();
};
//==================================================================
// Start express application
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.use(express.favicon());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({ secret: 'securedsession' }));
app.use(passport.initialize()); // Add passport initialization
app.use(passport.session()); // Add passport initialization
app.use(app.router);
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
//==================================================================
// routes
app.get('/', function(req, res){
res.render('index', { title: 'Express' });
});
app.get('/users', auth, function(req, res){
res.send([{name: "user1"}, {name: "user2"}]);
});
//==================================================================
//==================================================================
// route to test if the user is logged in or not
app.get('/loggedin', function(req, res) {
res.send(req.isAuthenticated() ? req.user : '0');
});
// route to log in
app.post('/login', passport.authenticate('local'), function(req, res) {
res.send(req.user);
});
// route to log out
app.post('/logout', function(req, res){
req.logOut();
res.send(200);
});
//==================================================================
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
答案 0 :(得分:8)
您需要允许在跨域设置Cookie
快递
res.header('Access-Control-Allow-Credentials', true);
在ajax设置中
xhrFields: {
withCredentials: true
}
答案 1 :(得分:2)
我认为rdegges有一部分想法,因为cookie和会话变量是使状态管理工作的一部分。我认为bodyParser也是必需的,但我在这里省略了它。
我在我的网站上使用Passport(对MongoDB用户表进行身份验证),这里是我代码的摘录。
/server.js:
var cookieParser = require('cookie-parser');
...
var passport = require('passport');
var expressSession = require('express-session');
var initPassport = require('./passport/init');
initPassport(passport);
...
self.app.use(cookieParser());
self.app.use(expressSession({secret: 'MYSECRETISVERYSECRET', saveUninitialized: true, resave: true}));
self.app.use(passport.initialize());
self.app.use(passport.session());
...
var routes = require('./routes/index')(passport);
self.app.use('/', routes);
/passport/init.js:
var login = require('./login');
var signup = require('./register');
var User = require('../models/user');
module.exports = function(passport) {
// Passport needs to be able to serialize and deserialize users to support persistent login sessions
passport.serializeUser(function(user, done) {
console.log('serializing user: ');
console.log(user);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
console.log('deserializing user:', user);
done(err, user);
});
});
// Setting up Passport Strategies for Login and SignUp/Registration
login(passport);
signup(passport);
}
/routes/index.js:
var passport = require('passport');
var User = require('../models/user');
...
var isAuthenticated = function (req, res, next) {
// if user is authenticated in the session, call the next() to call the next request handler
// Passport adds this method to request object. A middleware is allowed to add properties to
// request and response objects
if (req.isAuthenticated())
return next();
// if the user is not authenticated then redirect him to the login page
res.redirect('/login');
}
对于它的价值,我没有在任何地方看到你的isValidated()函数。
答案 2 :(得分:1)
可以这么多东西。
1。)PassportJS Facebook login isAuthenticated returns false even though authentication succeeds中的顺序(虽然在您的情况下顺序似乎正确)。
2。)没有Passport and Passport Local req.isAuthenticated always returns false
中的req.login()在这种情况下,我选择后者,但原因与该问题不同。
您已提供自己的LocalStrategy
。要让用户登录,您必须自己致电req.login()
。就像您要定义自己的自定义回调一样,如passport
文档中所述:http://passportjs.org/guide/authenticate/。
答案 3 :(得分:0)
您的浏览器是否保留了会话Cookie?听起来好像您的浏览器在登录后没有抓住您的会话cookie,这就是后续/loggedin
请求失败的原因。
答案 4 :(得分:0)
忘记添加
我遇到了同样的问题request.login()
on
app.post('/login',
function(request, response, next) {
console.log(request.session)
passport.authenticate('login',
function(err, user, info) {
if(!user){ response.send(info.message);}
else{
request.login(user, function(error) {
if (error) return next(error);
console.log("Request Login supossedly successful.");
return response.send('Login successful');
});
//response.send('Login successful');
}
})(request, response, next);
}
);
还要确保您有以下order进行初始化
var session = require('express-session');
// required for passport session
app.use(session({
secret: 'secrettexthere',
saveUninitialized: true,
resave: true,
// using store session on MongoDB using express-session + connect
store: new MongoStore({
url: config.urlMongo,
collection: 'sessions'
})
}));
// Init passport authentication
app.use(passport.initialize());
// persistent login sessions
app.use(passport.session());
答案 5 :(得分:0)
在我的情况下,我尝试了JMeas建议的解决方案来手动调用会话保存,但它无法正常工作
https://github.com/jaredhanson/passport/issues/482
req.session.save(function() { successRedirect(); })
经过一些实验,我只是将app.use(session({...}))移到所有中间件调用的顶部,现在req.isAuthenticated()按预期工作。我认为,会话设置应该作为第一个中间件或者至少在设置cookie之前。
通话中断:
var app = express();
app.use(query.json());
app.use(query.urlencoded({ extended: false }));
app.use(cookies());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
secret: 'card',
resave: true,
saveUninitialized: true
}));
app.use('/', routes); // this is where I call passport.authenticate()
固定电话:
app.use(session({
secret: 'card',
resave: true,
saveUninitialized: true
}));
app.use(query.json());
app.use(query.urlencoded({ extended: false }));
app.use(cookies());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(passport.session());
app.use('/', routes);