护照身份验证 req.isAuthenticated 始终为 false
Posted
技术标签:
【中文标题】护照身份验证 req.isAuthenticated 始终为 false【英文标题】:Passport Authentication req.isAuthenticated is always false 【发布时间】:2017-11-01 16:33:21 【问题描述】:我的身份验证系统未按预期工作。
首先我想向你展示我的 node.js 文件
//Initialize Express Web Server
var express = require('express');
var app = express();
var http = require("http").Server(app);
var lusca = require('lusca');
var io = require("socket.io")(http);
//require needs
var api = express.Router();
var ejs = require('ejs');
var expressValidator = require("express-validator");
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var LocalStrategy = require('passport-local').Strategy;
var session = require('express-session');
var passport = require('passport');
var morgan = require('morgan');
var mongo = require('mongodb');
var MongoStore = require('connect-mongo')(session);
//Connect to MongoDB
var mongoose = require('mongoose');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
//Resolving paths with nodejs
var path = require('path');
app.use(express.static(path.join(__dirname+"/MP/")));
//cookie parser middleware
app.use(cookieParser());
//Body Parser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded(extended:false));
//Init Sessions
app.use(session(
secret:'SOME_HIDDEN_TEXT',
cookie:httpOnly:true/*, secure: true*/,
saveUninitialized: false,
resave: false,
store: new MongoStore(mongooseConnection: mongoose.connection, autoReconnect: true)
));
//Init Passport
app.use(passport.initialize());
app.use(passport.session());
app.use(expressValidator(
errorFormatter: function(param, msg, value)
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length)
formParam += '[' + namespace.shift() + ']';
return
param : formParam,
msg : msg,
value : value
;
));
//Security
app.use(morgan('dev'));
//app.use(lusca.csrf());
/*app.use(lusca.csp(
"policy":
"default-src":"'self'",
"script-src":"'self' 'https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/*'",
"img-src":"'self' 'http://placehold.it/*'",
"connect-src":"'self'",
"font-src":"*",
"style-src":"'self' 'unsafe-inline' *"
));*/
app.use(lusca.hsts(maxAge:31536000));
app.use(lusca.xframe('SAMEORIGIN'));
app.use(lusca.p3p('ABCDEF'));
app.use(lusca.xssProtection(true));
app.use(lusca.nosniff());
//Init API
var User = require(path.join(__dirname+"/model/user"));
require("./MP/routes/api")(api);
app.use("/api", api);
/*app.use(function(req, res, next)
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', "http://localhost:3000");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method)
res.send(200);
else
next();
);*/
//Setting up listening port
var port = 3000;
io.on("connection", function(socket)
console.log("user connected");
);
app.set('view engine', 'ejs');
app.set("views", path.resolve(__dirname,"MP","view"));
//Render View for Angular
app.get('/', function(req,res)
res.render("index.ejs");
console.log(req.headers.origin);
);
http.listen(port,function()
console.log('SERVER LISTENING ON PORT: '+port);
);
接下来是我的 Angular 应用
"use strict";
var app = angular.module("app", ["ngRoute","ui.router", "ngSanitize","ngResource"]);
app.config(["$stateProvider" , "$urlRouterProvider", "$locationProvider" , function ($stateProvider , $urlRouterProvider, $locationProvider, loginService)
$stateProvider
.state("login",
url: "/",
templateUrl: "partials/index.html",
controller: "indexCtrl"
)
.state("register",
url:"/register",
templateUrl: "partials/register.html",
controller: "indexCtrl"
)
.state("home",
url: "/en/",
abstract: true,
templateUrl: "partials/home.html",
resolve:
loggedIn: checkLogin
)
.state("home.news",
url: "",
templateUrl: "partials/news.html",
resolve:
loggedIn: checkLogin
)
.state("home.gamer",
url: "gamer/",
templateUrl: "partials/gamer.html",
resolve:
loggedIn: checkLogin
)
.state("home.search",
url: "search/",
templateUrl: "partials/search.html",
resolve:
loggedIn: checkLogin
)
.state("home.games",
url: "games/",
templateUrl: "partials/games.html",
resolve:
loggedIn: checkLogin
)
.state("home.verify",
url: "verify/",
templateUrl: "partials/verify.html",
resolve:
loggedIn: checkLogin
);
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(
enabled: true,
requireBase: false
);
]);
function checkLogin(loginService)
return loginService.loggedIn();
这是我的登录服务
"use strict";
app.factory("loginService",["Api", "$location", "$state", "$q", "$rootScope", function (Api,$location,$state,$q,$rootScope)
return
login: function (user,scope)
Api.login.post(user, function(regRes)
console.log(regRes.data);
if(regRes.data.error)
scope.error = error : regRes.data.error;
else if(regRes.data.success === 1)
$state.go("home.news");
);
,
loggedIn: function()
var deferred = $q.defer();
Api.login.get(function(user)
if(user.data != "0")
$rootScope.currentUser = user;
deferred.resolve();
else
$rootScope.currentUser = null;
deferred.reject();
$state.go("login");
);
return deferred.promise;
]);
最后但并非最不重要的是我的 api
'use strict';
var User = require("../../model/user");
var passport = require("passport");
var LocalStrategy = require("passport-local").Strategy;
passport.use(new LocalStrategy(usernameField: "e", passwordField: "p",function(email, password, done)
var user = new User();
user.findEmail(escape(email),function(err, user)
if(err)
throw err;
if(!user)
return done(null,false, error: "Email or Password is wrong. Please try again.");
user.comparePw(escape(password),user.password,function(err, isMatched)
if(!isMatched)
return done(null,false, error: "Email or Password is wrong. Please try again.");
else
return done(null,user);
);
);
));
passport.serializeUser(function(user,done)
done(null, user.id);
);
passport.deserializeUser(function(user,done)
var user = new User();
user.findUserById(user, function(err, user)
done(err,user);
);
);
module.exports = function(router)
router.get("/user", function(req, res)
var user = new User();
user.getGamer(function(err,response)
if(err)
throw err;
else
res.json(response);
);
);
router.post("/user/login", function(req, res, next)
passport.authenticate('local', session: true,function(err, user, info)
console.log(user + " " + info + " " + err);
if (err) return next(err);
if (!user) return res.json(error: "Email or Password is wrong. Please try again.");
if(user.confirm == 0) return res.json(error: "Please confirm your email address and try again.")
console.log(req.user);
req.logIn(user, function(err)
console.log(req.session.id);
console.log(req.user); //req.user is defined
console.log(req.isAuthenticated()); //req.isAuthenticated() is true
if (err) return next(err);
res.json(success: 1);
);
)(req, res, next);
);
router.get("/user/login", function(req, res, next)
console.log(req.isAuthenticated()); //returns false
res.send(req.isAuthenticated() ? req.user: "0"); //send object with data:"0";
);
;
更新:这是我的 API 服务
app.factory("Api", ["$resource", function($resource)
return
gamer: $resource("/api/user/:id", _id: "@id",
"get":
method: "GET",
interceptor:
response: function(response)
return response;
,
"post":
method: "POST",
interceptor:
response: function(response)
return response;
),
login: $resource("/api/user/login", ,
"post":
method: "POST",
interceptor:
response: function(response)
return response;
,
"get":
method: "GET",
interceptor:
response: function(response)
return response;
)
]);
在我调用loggedIn 函数时,我得到了一个带有数据的对象的响应:“0”。我不知道为什么 req.isAuthenticated() 在通过护照成功登录时总是错误的。一个名为 connect.sid 的会话 cookie 已正确设置,并获得与存储在 mongoose 数据库中的会话 cookie 相同的值。如果我在登录后立即通过 console.log isAuthenticated,我会得到 true 的响应,否则它总是 false。我也尝试允许 CORS,但它没有奏效。我在谷歌上搜索了一整天以找到解决方案。有人可以帮助我吗?
问候中国
【问题讨论】:
当你调用你的 API 时,你把withCredentials: true
放了吗?否则,您的 AJAX 请求将无法获取 (httpOnly) cookie。
我更新了我的帖子。我认为我没有这样做:/
【参考方案1】:
尝试将withCredentials
参数放入您的请求中。
...
login: $resource("/api/user/login", ,
"post":
method: "POST",
withCredentials: true,
interceptor:
response: function(response)
return response;
,
"get":
method: "GET",
withCredentials: true,
interceptor:
response: function(response)
return response;
)
...
见:here
让我知道它是否有效!
【讨论】:
仍然返回 false :/【参考方案2】:好吧,我自己发现了。我最大的错误是我忘记为 cookie 解析器设置相同的密钥,如下所示。
app.use(cookieParser("SAME_SECRET")); //i let this blank
app.use(session(
secret:'SAME_SECRET',
cookie:httpOnly:true/*, secure: true*/,
saveUninitialized: true,
resave: true,
store: new MongoStore(mongooseConnection: mongoose.connection, autoReconnect: true)
));
【讨论】:
以上是关于护照身份验证 req.isAuthenticated 始终为 false的主要内容,如果未能解决你的问题,请参考以下文章
使用身份验证护照系统覆盖 laravel 中 apis url 的身份验证重定向