gpt4 book ai didi

node.js - 为什么在路由中调用时我的 Passport 身份验证函数不执行?

转载 作者:搜寻专家 更新时间:2023-10-31 23:08:17 25 4
gpt4 key购买 nike

我正在使用 Passport 来保护 MEAN 堆栈应用程序的前端和后端。该应用程序的结构如下:

monstermash
config // server configuration
public // static directory that will serve the entire Angular frontend
app
index.js // initialization of the server
models
index.js // mongoose schemas and models
passport
index.js // configuration for passport and all my strategies
routes
index.js // basic route definitions for the API (using functions defined under v1, below) and UI (routes defined inline here for simplicity's sake)
v1
index.js // all the functions called to power the API routes

这是 app/index.js,因为我知道有时需要以正确的顺序调用应用程序中间件:

var express = require('express');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var mongoose = require('mongoose');
var app = express();
var CONFIG = require('config').BASE;
var bcrypt = require('bcrypt-nodejs');
var passport = require('passport');
var flash = require('connect-flash');
var models = require('./models');

app.passport = require('./passport');
app.port = CONFIG.PORT;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(allowCrossDomain);
app.use(express.static('public'));
app.use(cookieParser());
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

var routes = require('./routes');

app.use(express.static('public', {redirect:false}));
routes(app)

module.exports = app

passport/index.js 看起来像这样。许多被注释掉的位只是为了将其简化为用于调试而被删除:

var models = require('../models')

passport = require('passport')
, LocalStrategy = require('passport-local').Strategy
, LocalAPIKeyStrategy = require('passport-localapikey-update').Strategy;

passport.use('localapikey', new LocalAPIKeyStrategy(
{apiKeyHeader:'x-auth-token'},
function(apikey, done) {
console.log('api key');
models.User.findOne({ apikey: apikey }, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
return done(null, user);
});
}
));

passport.use('local-signup', new LocalStrategy(
function (req, username, password, done) {
console.log('trying local');
models.User.findOne({
local: {username: username}, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
console.log('no user');
return done (null, false);
}

if (!user.validPassword(password)) {
console.log('bad pwd');
return done(null, false);
}
return done (null, user);
}
})
}
));

module.exports = passport;

此处包含 localaipkey 策略只是为了说明的工作原理,其配置方式与本地注册策略大致相同。

然后我的 routes/index.js 看起来像这样。登录表单的 HTML 在这里是内联的,因为这只是初步测试。请注意,除了检查验证之外,我没有做任何其他事情。包括此处的 API 路由之一也确实演示了它是如何设置的。此处的 UI 代码是直接从 Passport 教程中提取的,因为我回到绘图板并删除了我自己的代码。

var v1 = require('./v1');

// API routes as an example. This authentication is called before the route and works fine.

module.exports = function(app) {
/* API: V1 */
app.route('/v1/monster/:id')
.put(
app.passport.authenticate('localapikey', { session: false }),
v1.monster.update)
.delete(
app.passport.authenticate('localapikey', { session: false }),
v1.monster.delete
);

// My test login routes. Here, authenticate is called inside the route because it's the handler for logging in.

app.route('/login')
.post(
function (req, res) {
console.log(req.body);
app.passport.authenticate('local-signup', {
successRedirect: '/root',
failureRedirect: '/fail'
});
})
.get(function (req,res) {
res.send('<!-- views/login.ejs -->\
<!doctype html>\
<html>\
<head>\
<title>Node Authentication</title>\
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->\
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->\
<style>\
body { padding-top:80px; }\
</style>\
</head>\
<body>\
<div class="container">\
\
<form action="/login" method="post">\
<div>\
<label>Username:</label>\
<input type="text" name="username"/>\
</div>\
<div>\
<label>Password:</label>\
<input type="password" name="password"/>\
</div>\
<div>\
<input type="submit" value="Log In"/>\
</div>\
</form>\
\
</div>\
</body>\
</html>');
});

因此该表单提交带有表单数据的POST:/login 请求。表单正文在 req.body 中,但我在验证函数中的 console.log 消息从未被记录。表单提交只是挂了又挂了;该路由上没有 res.send(),因为身份验证要么通过,要么失败,永远不会到达那里,但是整个 app.passport.authenticate() 函数是完全被绕过了。

我在这方面做了很多试验和错误,我发现如果我用策略名称调用 app.passport.authenticate()即使没有注册,同样的事情也会发生:没有失败消息,它只是继续沿着路线前进,就像它根本不存在一样。所以也许问题是这正在发生并且它没有识别正在注册的local-signup策略,虽然我不知道为什么会这样并且找到 localapikey 策略。

旁注,实际上我正在使用表单中设置的 usernamepassword 进行测试;我从某个尝试空提交或无密码提交但没有看到他们的验证函数执行的人那里发现了一个 SO 问题,所以我确定不是那个问题。

最佳答案

因此,我的问题的答案基本上是“因为您不能在路由内调用身份验证函数。”

我不会删除这个问题,因为我知道我是从某处的 Passport 教程中得到这个想法的,因此其他人以后可能会遇到同样的问题。

关于node.js - 为什么在路由中调用时我的 Passport 身份验证函数不执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36231932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com