身份验证问题
Trouble with authentication
在使用护照本地策略实现restful api的身份验证时,我面临一个混淆问题。
注意:当我在index.js中执行所有操作时,我成功地获得了身份验证。但我想在类中使用,以获得更好的代码分离。
I have a passport.js Module
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var mysql = require('mysql');
var dbconfig = require('./database');
var connection = mysql.createConnection(dbconfig.connection);
module.exports = function(passport) {
// passport needs ability to serialize and unserialize users out of session
passport.serializeUser(function (user, done) {
//console.log("SER");
console.log(user),
done(null, user);
});
passport.deserializeUser(function (user, done) {
console.log("XXXX");
console.log(user);
connection.query("SELECT * FROM users WHERE name = ? ",user.name, function(err, rows){
console.log("DER");
console.log(rows);
done(err, rows[0]);
});
});
// passport local strategy for local-login, local refers to this app
passport.use('local-login', new LocalStrategy(
function (username, password, done) {
console.log("hhh");
console.log(username);
connection.query("SELECT * FROM users WHERE name = ? ",username, function(err, rows){
console.log(rows);
return done(err, rows[0]);
});
})
);
// route middleware to ensure user is logged in
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.sendStatus(401);
}
};
这是我的控制器类:
class AuthenticateController {
constructor(router, passport) {
this.router = router;
this.registerRoutes();
this.passport = passport;
}
registerRoutes() {
this.router.post('/login/:username/:password', this.login.bind(this));
//this.router.get('/logout', this.logout.bind(this));
this.router.get('/content', this.content.bind(this));
}
login(req, res) {
this.passport.authenticate("local-login", { failureRedirect: "/login"}),
res.redirect("/content");
}
content(req, res ) {
console.log(req.user);
if (req.isAuthenticated()) {
res.send("Congratulations! you've successfully logged in.")
} else {
res.sendStatus(401);
}
}
isLoggedIn(req, res, next) {
console.log(req.user);
if (req.isAuthenticated())
return next();
res.sendStatus(401);
}
}
module.exports = AuthenticateController;
控制器从我的index.js中获得路由器和护照作为参数的完整配置。
//index.jsvar express = require('express')
, cors = require('cors')
, app = express()
, passport = require('passport')
, morgan = require('morgan');
require('./config/passport')(passport); // pass passport for configuration
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(require('express-session')({secret: 'vidyapathaisalwaysrunning',
resave: true,
saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(cors());
var apiRouter = express.Router();
app.use('/api', apiRouter);
//
var apiV1 = express.Router();
apiRouter.use('/v1', apiV1);
var authenticateApiV1 = express.Router();
apiV1.use('/auth', authenticateApiV1);
var AuthenticateController = require('./controllers/authenticate');
var ac = new AuthenticateController(authenticateApiV1, passport); //pass in our fully configured passport
//If I call this /login instead of the /auth/login/ in the Controller Class it works!
//app.post("/login",
// passport.authenticate("local-login", { failureRedirect: "/login"}),
// function (req, res) {
// res.redirect("/content");
// });
什么在工作,什么不工作
general中的Authentication工作正常。在我发布的index.js中,您看到app.post("/login", ...
。如果我调用这个,认证成功,如果我尝试到达受限内容在/auth/content/req.user
中有一个值(用户对象),我可以成功调用req.isAuthenticated()
。
但是,如果我使用/auth/login/username/password
的身份验证,则req.user
在试图到达受限制的内容时未定义。我没有得到错误和/auth/login/username/password/
HTTP代码301的响应- '重定向到/content。
我目前不知道我在这里做错了什么,我对Node/express/passport这个话题很陌生。
希望有人有一个主意。如果你还需要什么帮助,请在评论中提到,我会尽我所能为你提供你所需要的一切。
感谢编辑:我最近试图在登录函数中读取req.user
,即使在那里它是未定义的
login(req, res) {
this.passport.authenticate("local-login", { failureRedirect: "/login"}),
console.log(req.user) //undefined
res.redirect("/content");
}
我猜这可能是一些异步问题,我应该使用一些回调函数,但我不知道如何在我的login()
我面临的另一个问题是isLoggedIn()请求的集成。
如果我这样做:
registerRoutes() {
this.router.get('/', this.isLoggedIn, this.getUsers.bind(this));
this.router.get('/:id', this.getSingleUser.bind(this));
}
结果是401 - Unauthorized
isLoggedIn()
中的console.log(req.user);
结果为undefined
但是如果我不调用isLoggedIn()
而调用console.log(req.user);
,则用户对象存在
对于本地策略,带护照身份验证的回调的正确使用方法如下:
function(req, res, next){
passport.authenticate('local-login', function(err, user, info){
if(err)
return logger.log('error', err);
if(user)
req.login(user, function(err){
if(err) return next(err);
return res.json({'success': true});
});
if(!user)
return res.json({'error':true, 'message': info.message, 'type': info.type});
})(req, res, next);
}
请注意使用req.login()来显式设置会话中的用户
我发现唯一奇怪的是你的路由声明是不同的。
在AuthenticateController
中,路由声明为:
this.router.post('/login/:username/:password', ...
而在index.js
中,路由被简单地声明为
app.post("/login", ...
您的客户端如何向服务器提交登录凭据?如果它是由形式,像教程,它可能是有:username
和:password
声明为路由参数,但被发送的形式混乱与护照?
尝试完全像index.js
一样注册路由
this.router.post('/login', ...
编辑:我又发现了另一种差异。在AuthenticateController
中,res.redirect("/content");
没有包装在回调中。所以在Authenticate
结束运行之前,它被执行。
在index.js
示例中,passport被用作路由中间件:
app.post("/login",
passport.authenticate("local-login", { failureRedirect: "/login"}),
function (req, res) {
res.redirect("/content");
});
而在passport.js
中,它是在回调中。考虑在路由中声明它:
registerRoutes() {
this.router.post('/login', this.passport.authenticate("local-login", { failureRedirect: "/login"}), this.login.bind(this));
(...)
}
login(req, res) {
res.redirect("/content");
}
哦,更好的是,为什么不使用passport's
选项来声明成功和失败的重定向,因为这似乎是你所做的一切:
login(req, res) {
this.passport.authenticate("local-login", { successRedirect: "/content", failureRedirect: "/login" });
}
您将this.login.bind(this)
作为中间件传递给this.router.post('/login/:username/:password', this.login.bind(this));
,但login(req, res)
仅响应res.redirect("/content");
的请求,即重定向到/content
就像你说的,你需要提供一个回调来处理从护照中间件验证回调返回的用户。
app.post("/login",
passport.authenticate("local-login", { failureRedirect: "/login"}),
function (req, res) {
console.log(req.user); // log user in console
res.json({user: req.user}); // send user as json response
});
@divsingh提到的自定义回调是如果你想明确地控制设置会话,错误消息和重定向请求。其他信息请访问http://passportjs.org/docs
- Sencha Touch和远程服务器上的身份验证
- Javascript清除缓存以清除基本身份验证凭据
- REST的面向公众的身份验证机制
- 当需要身份验证时,ui路由器不会重定向
- CRM身份验证问题
- 获取json结果的身份验证问题
- 在Internet Explorer 11中使用SoundCloud进行身份验证时出现问题
- jQuery,CORS,JSON(不带填充)和身份验证问题
- Facebook标签/页面身份验证问题:getLoginStatus总是返回not_authorized
- 使用 JavaScript 问题使用 LinkedIn API 进行身份验证
- Chrome 的 HTTP BASIC 身份验证注销问题
- MongoError: 身份验证失败.- 连接到MongoLab时出现问题
- 使用基于Java EE表单的身份验证时出现Javascript问题
- 此HTTP Get-Basic身份验证代码有什么问题
- P4身份验证问题
- 身份验证问题
- Firebase匿名身份验证问题
- 使用Everyauth的github身份验证的承诺问题
- Google使用OAuth2身份验证从JavaScript客户端接触API问题
- JsonWebToken用户身份验证问题