身份验证发出带有护照和Nginx作为代理服务器的Node.js

Joo*_*Aué 3 authentication nginx node.js express passport.js

我正在运行使用Passport.js在端口3000上进行身份验证的Node应用程序.Nginx用作代理服务器侦听端口80,代理将请求传递到端口3000.Passport.js用于验证用户.

身份验证协议如下:用户请求example.com,如果他未登录,则会重定向到example.com/login.成功登录后,用户将再次重定向到example.com.

  • 当我尝试使用Ipad上的Safari 6和Internet Explorer 9(怀疑客户有同样的问题)登录时,会出现此问题.当使用正确的凭据时,应用程序会重定向到example.com/login而不是example.com/.

  • 例如,Chrome 40中不会出现此问题.

  • 在Safari中使用example.com:3000避免使用nginx时不会出现此问题.
  • 更糟糕的是:有时候它没有明显的原因.

我怀疑它与Nginx以及请求文件的顺序有关.

Nginx配置:

server {
    listen 80;
    location / {
            proxy_pass http://127.0.0.1:3000;
    }
}
Run Code Online (Sandbox Code Playgroud)

部分应用代码:

app.post('/api/login', function (req, res, next) {
passport.authenticate('local-login', function (err, user, info) {
  if (err) {
    return next(err);
  }
  if (!user) {
    return res.status(401).send(info);
  }
  req.logIn(user, function (err) {
    if (err) {
      return next(err);
    }
    return res.send({
      username: user.username
    });
  });
})(req, res, next);
});

app.get('/', isLoggedIn, function (req, res) {
  res.sendFile(__dirname + '/client/views/index.html');
});


function isLoggedIn(req, res, next) {
  if (!req.isAuthenticated()) {
    res.redirect('/login');
  } else {
    next();
  }
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有人可以帮助我.我很乐意在需要时提供额外的代码或解释.

Joo*_*Aué 6

Nginx原来与之无关.通过使用example.com:3000直接访问,偶尔也会出现问题.

我注意到浏览器曾说过我访问过example.com并且正在显示example.com/login.我在互联网上找不到任何证据,但我怀疑Safari/IE9缓存重定向的页面并将其链接到原始URL.所以这是接下来发生的事情的故事情节.

  1. 用户浏览example.com/
  2. 重定向到example.com/login(浏览器缓存example.com/但保存登录页面)
  3. 用户登录并重定向到example.com/
  4. 浏览器具有/在缓存中并加载登录页面.
  5. 无法解释的错误和开发人员的头痛.

通过添加中间件来"解决",在请求时不添加缓存头.

app.get('/', isLoggedIn, noCache, function (req, res) {
  res.sendFile(__dirname + '/client/views/index.html');
});

function noCache(req, res, next) {
  res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
  res.header('Expires', '-1');
  res.header('Pragma', 'no-cache');
  next();
}
Run Code Online (Sandbox Code Playgroud)