Node.js 来自 http 来源的 Express Websocket 客户端?

Node.js Express Websocket clients coming from http origin?

我有一个使用 websocket 与 Node.js Express 服务器通信的网络应用程序。

在验证 websocket 连接时,我检查了请求的 ORIGIN header(以及一些其他参数以确保它们是合法的)

预期的请求是“https://www.mywebsite.com”或“https://mywebsite.com”

如果 ORIGIN header 不是预期的,我们将踢用户。

然后我注意到有些人在他们的套接字连接看起来没问题时可能会被踢,但是 ORIGIN 是“http://mywebsite.com”。我们很快查看了一下,发现可以http访问该网站。我们添加了一段这样的重定向代码:

const server = express() 
  .enable('trust proxy')
  .use((req, res, next) => {
      req.secure ? next() : res.redirect('https://' + req.headers.host + req.url)
  })

现在理论上,任何访问 http 版本网站的人都应该被重定向到 https。

但是,即使完成此重定向,我们仍然注意到有人被踢了,因为他们的来源是 http 而不是 https。为什么会这样?是否有可能某些用户永远无法使用 https?

这是在 Heroku 上重定向到 https 的正确方法:

Under the hood, Heroku router (over)writes the X-Forwarded-Proto and the X-Forwarded-Port request headers. The app must check X-Forwarded-Proto and respond with a redirect response when it is not https but http.

取自:https://help.heroku.com/J2R1S4T8/can-heroku-force-an-application-to-use-ssl-tls

这是一些您可以使用的示例代码:

app.use((req, res, next) => {
  if (req.header('x-forwarded-proto') !== 'https') {
    res.redirect(`https://${req.header('host')}${req.url}`)
  } else {
    next()
  }
})

您的代码不起作用的原因是 Heroku 为您执行 SSL 终止并提供证书,这意味着 Heroku 路由器和您的 Node.js 服务器之间的连接不安全并且 req.secure return 错误: https://devcenter.heroku.com/articles/http-routing#routing
更正:因为您设置了信任代理,这意味着 req.protocol 将设置为 https,而 req.secure 将 return 为真,因此您的代码将起作用。