认证问题
Trouble with authentication
我在使用护照本地策略为我的 restful api 实施身份验证时遇到了一个混淆问题。
注意:
当我在我的 index.js 中完成所有这些时,我的身份验证工作成功。但我想在 Classes 中使用以更好地分离代码。
我有一个 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:
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;
Controller 从我的 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");
// });
什么有效,什么无效
general 中的身份验证正在运行。在我发布的 index.js 中,您会看到 app.post("/login", ...
。如果我调用这个,则身份验证成功,如果我尝试访问 /auth/content 中的 受限内容 / req.user
有一个值(用户对象)并且我可以成功调用 req.isAuthenticated()
.
但是,如果我使用来自 /auth/login/username/password
的身份验证,那么在尝试访问受限内容时 req.user
是 undefined。
我没有收到任何错误和 /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()
中应用它
编辑 2:
我面临的另一个问题是 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);
结果未定义。
但是如果我调用第一个路由而不调用 isLoggedIn()
并执行 console.log(req.user);
用户对象存在。
我唯一觉得奇怪的是你的路由声明不同。
在 AuthenticateController
中,路由声明为:
this.router.post('/login/:username/:password', ...
而在index.js
中,路由被简单地声明为
app.post("/login", ...
您的客户端如何向服务器提交登录凭据?如果是通过表单,比如 the tutorial,是否会将 :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
option to declare both success and failure redirects,因为这似乎是您正在做的全部事情:
login(req, res) {
this.passport.authenticate("local-login", { successRedirect: "/content", failureRedirect: "/login" });
}
本地策略的护照认证回调正确使用如下:
function(req, res, next){
passport.authenticate('local-login', 函数(错误, 用户, 信息){
如果(错误)
return logger.log('error', 错误);
如果(用户)
req.login(用户,函数(错误){
如果(错误)return 下一个(错误);
return res.json({'success': 真});
});
如果(!用户)
return res.json({'error':true, 'message': info.message, 'type': info.type});
})(要求, 资源, 下一步);<br>
}
请注意使用 req.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 提到的 custom 回调是如果您想明确控制设置会话、错误消息和重定向请求。可以在 http://passportjs.org/docs
下找到任何其他信息
我在使用护照本地策略为我的 restful api 实施身份验证时遇到了一个混淆问题。
注意: 当我在我的 index.js 中完成所有这些时,我的身份验证工作成功。但我想在 Classes 中使用以更好地分离代码。
我有一个 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:
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;
Controller 从我的 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");
// });
什么有效,什么无效
general 中的身份验证正在运行。在我发布的 index.js 中,您会看到 app.post("/login", ...
。如果我调用这个,则身份验证成功,如果我尝试访问 /auth/content 中的 受限内容 / req.user
有一个值(用户对象)并且我可以成功调用 req.isAuthenticated()
.
但是,如果我使用来自 /auth/login/username/password
的身份验证,那么在尝试访问受限内容时 req.user
是 undefined。
我没有收到任何错误和 /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()
编辑 2:
我面临的另一个问题是 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);
结果未定义。
但是如果我调用第一个路由而不调用 isLoggedIn()
并执行 console.log(req.user);
用户对象存在。
我唯一觉得奇怪的是你的路由声明不同。
在 AuthenticateController
中,路由声明为:
this.router.post('/login/:username/:password', ...
而在index.js
中,路由被简单地声明为
app.post("/login", ...
您的客户端如何向服务器提交登录凭据?如果是通过表单,比如 the tutorial,是否会将 :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
option to declare both success and failure redirects,因为这似乎是您正在做的全部事情:
login(req, res) {
this.passport.authenticate("local-login", { successRedirect: "/content", failureRedirect: "/login" });
}
本地策略的护照认证回调正确使用如下:
function(req, res, next){
passport.authenticate('local-login', 函数(错误, 用户, 信息){
如果(错误)
return logger.log('error', 错误);
如果(用户)
req.login(用户,函数(错误){
如果(错误)return 下一个(错误);
return res.json({'success': 真});
});
如果(!用户)
return res.json({'error':true, 'message': info.message, 'type': info.type});
})(要求, 资源, 下一步);<br>
}
请注意使用 req.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 提到的 custom 回调是如果您想明确控制设置会话、错误消息和重定向请求。可以在 http://passportjs.org/docs
下找到任何其他信息