Node.js 通过 Apache-Redirect 代理进行护照身份验证

Node.js Passport Authentification through Apache-Redirect Proxy

我正在构建一个带有集成护照帐户系统的 node.js 应用程序。因为我在 uberspace.de 上托管,所以我需要像这样在主网络根目录中配置我的 .htaccess:

RewriteEngine On
RewriteRule ^(.*) http://localhost:34457/ [P]

我的快速登录路径是:(可在 /api/auth/login 访问)

router.post('/login', passport.authenticate('login', { 
    successRedirect: '/account',
    failureRedirect: '/login?error=true'
}));

根据我对 Passport 的理解,如果成功登录,我应该被重定向到 /account,如果没有,则重定向到 /login?error=true

但是如果我使用

执行 POST
url --data "email=foo@bar.com&password=test" http://[domain]/api/auth/login

结果是:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>502 Proxy Error</title>
</head><body>
<h1>Proxy Error</h1>
<p>The proxy server received an invalid
response from an upstream server.<br />
The proxy server could not handle the request <em><a href="/api/auth/login">POST&nbsp;/api/auth/login</a></em>.<p>
Reason: <strong>Error reading from remote server</strong></p></p>
<hr>
<address>Apache/2.2.15 (CentOS) Server at [domain] Port 80</address>
</body></html>

如果我在 Chrome 中通过 html 形式(方法:POST,操作:/api/auth/login)执行相同的查询,我将被重定向到 /api/auth/login%5E(显然 returns 一个 404)。

像这样的简单重定向有效:

router.post('/redirectToHome', function(req, res, next) {
    res.redirect(302, '/'); 
});

但即使我在调用时执行此功能/api/auth/login

router.post('/login', function(req, res, next) {
    passport.authenticate('login', function(err, user, info) {
        if (err) return next(err);  
        if (!user) {
            console.log(info);
            return res.json(401, {success: false});
        } else {
            console.log(info);
            return res.json(200, {success: true});
        }
    })(req, res, next); 
});

我仍然会被重定向到 /api/auth/login%5E

我的 login 身份验证策略实现为:

var LocalStrategy   = require('passport-local').Strategy;
var User = require('../models/user');
var bCrypt = require('bcrypt-nodejs');

module.exports = function(passport){

    passport.use('login', new LocalStrategy({
            usernameField: 'email',
            passReqToCallback : true
        }, function(req, email, password, done) { 
            // check in mongo if a user with username exists or not
            User.findOne({ 'email' :  email }, 
                function(err, user) {
                    // In case of any error, return using the done method
                    if (err)
                        return done(err);
                    // Username does not exist, log the error and redirect back
                    if (!user){
                        console.log('User Not Found with email '+email);
                        return done(null, false, req.flash('message', 'User Not found.'));                 
                    }
                    // User exists but wrong password, log the error 
                    if (!isValidPassword(user, password)){
                        console.log('Invalid Password');
                        return done(null, false, req.flash('message', 'Invalid Password')); // redirect back to login page
                    }
                    // User and password both match, return user from done method 
                    // which will be treated like success
                    return done(null, user);
                });
            }));
    var isValidPassword = function(user, password){
        return bCrypt.compareSync(password, user.password);
    }
}

即使login-router这样写:

router.post('/login', function(req, res, next) {
    passport.authenticate('login', function(err, user, info) {
        if (err) return next(err);  
        if (!user) {
            console.log(info);
            return res.json(401, {success: false});
        } else {
            console.log(info);
            return res.json(200, {success: true});
        }
    })(req, res, next); 
});

我仍然被重定向到 /api/auth/login%5E

我的护照login-策略是这样实现的:

var LocalStrategy   = require('passport-local').Strategy;
var User = require('../models/user');
var bCrypt = require('bcrypt-nodejs');

module.exports = function(passport){

    passport.use('login', new LocalStrategy({
            usernameField: 'email',
            passReqToCallback : true
        }, function(req, email, password, done) { 
            // check in mongo if a user with username exists or not
            User.findOne({ 'email' :  email }, 
                function(err, user) {
                    // In case of any error, return using the done method
                    if (err)
                        return done(err);
                    // Username does not exist, log the error and redirect back
                    if (!user){
                        console.log('User Not Found with email '+email);
                        return done(null, false, req.flash('message', 'User Not found.'));                 
                    }
                    // User exists but wrong password, log the error 
                    if (!isValidPassword(user, password)){
                        console.log('Invalid Password');
                        return done(null, false, req.flash('message', 'Invalid Password')); // redirect back to login page
                    }
                    // User and password both match, return user from done method
                    // which will be treated like success
                    return done(null, user);
                });
            }));
    var isValidPassword = function(user, password){
        return bCrypt.compareSync(password, user.password);
    }
}

有什么问题?

实际上,我的问题是一些不可见的字符,它将我重定向到其他页面,然后导致其他一些事情出错。