身份验证问题
我在使用护照本地策略执行我的restful api身份验证时遇到了混淆问题。身份验证问题
说明: 当我在index.js中完成所有操作时,我的认证工作成功。但我想在类中使用更好的代码分离。
我有一个passport.js模块
// 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.js
var 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");
// });
什么是工作,什么是不工作
的认证以一般工作。在我发布的index.js中,你会看到app.post("/login", ...
。如果我呼叫此身份验证成功,并且如果我尝试访问受限内容 in/auth/content/req.user
有一个值(用户对象),并且我可以成功呼叫req.isAuthenticated()
。
但是,如果我使用/auth/login/username/password
的验证,req.user
是未定义当试图达到受限制的内容。 我得到没有错误和/auth/login/username/password/
HTTP代码301 - '重定向到/内容的回应。
我目前不知道什么I'm做错了,并I'm相当新的节点/快递/护照的话题..
希望有人有一个想法。如果您需要别的帮助我,请在评论中提及它,我会尽我所能为您提供您所需的一切。
感谢
编辑:
我最近尝试在登录功能来读取req.user
,甚至还有它是不确定的
login(req, res) {
this.passport.authenticate("local-login", { failureRedirect: "/login"}),
console.log(req.user) //undefined
res.redirect("/content");
}
我想这可能是一些异步的问题,我应该使用一些回调函数,但我不知道如何将其应用于我的login()
编辑2:
我正面临的另一个问题是isLoggedIn()请求的集成。
如果我这样做:
registerRoutes() {
this.router.get('/', this.isLoggedIn, this.getUsers.bind(this));
this.router.get('/:id', this.getSingleUser.bind(this));
}
它导致401 - Unauthorized
一个console.log(req.user);
在isLoggedIn()
结果不确定。
但是,如果我呼叫第一条路线而不呼叫isLoggedIn()
并且执行console.log(req.user);
用户对象存在。
正确使用回拨与Passport身份验证本地策略可以如下:
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的()明确设置用户以s分裂国家。
我唯一觉得奇怪的是你的路由声明是不同的。
在AuthenticateController
路线被声明为:
this.router.post('/login/:username/:password', ...
虽然index.js
,路由就只作为
app.post("/login", ...
如何在您的客户端提交的登录凭证到服务器申报?如果是the tutorial等形式,是否可以将:username
和:password
声明为路由参数,但是是否通过护照形式发送?
尝试注册的路线完全一样index.js
this.router.post('/login', ...
编辑: 我发现了另一个dicrepancy。 AuthenticateController
res.redirect("/content");
不包含在回调中。所以它在Authenticate
完成运行之前正在执行。
在index.js
例如,护照被用作路由中间件:
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");
}
O,更好的是,为什么不使用passport's
option to declare both success and failure redirects,因为这似乎是所有你正在做的:
login(req, res) {
this.passport.authenticate("local-login", { successRedirect: "/content", failureRedirect: "/login" });
}
找到,但它没有帮助。我正在使用Chrome插件ARC发送请求。任何其他想法? –
@elsololobo看看我的编辑。我提出了其他一些可以帮助您的更改 – fmello
你传入this.login.bind(this)
作为中间件this.router.post('/login/:username/:password', this.login.bind(this));
但login(req, res)
只响应该请求与res.redirect("/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
感谢您的回答。您的解决方案是唯一的解决方案,我没有遇到超时,它似乎工作!谢谢 –
很高兴我能帮到你。 – divsingh