【问题标题】:Node server HTTPS and HTTP on AzureAzure 上的节点服务器 HTTPS 和 HTTP
【发布时间】:2013-11-21 06:10:36
【问题描述】:

我正在尝试在 Azure 上首次部署我的 nodejs 应用程序。

我启动了两台服务器:

  // public server
  publicServer.listen(publicServerPort, function() {
    console.log('Public server started and listening on port ' + publicServerPort);
  });

  // API server
  var credentials = {
    key : fs.readFileSync(key, 'utf8'),
    cert: fs.readFileSync(cert, 'utf8')
  };

  https
    .createServer(credentials, serverAPI)
    .listen(serverAPIPort, function(){
      console.log('API server started and listening on port ' + serverAPIPort);
    });

我读到 Azure 自己处理重定向到 HTTPS,而且我不能有两台服务器,因为只有一个端口是开放的。

如果我同时使用process.env.PORT,我会得到(逻辑上):

Unaught exception: Error: listen EADDRINUSE

如果我使用公共 process.env.PORT 和 HTTPS 443:

Unaught exception: Error: listen EACCES

我可以有两台服务器吗? 如果不是如何正确处理路由(http和https不同)? 比如通过协议检测?

感谢您的帮助。

【问题讨论】:

  • 如果您可以提供至少部分 Azure 服务定义文件(您如何配置 Runtime > Environment 和 Endpoints),那将是非常有益的。您还使用 Azure 网站或 Azure 云服务吗?

标签: node.js azure https


【解决方案1】:

我运行具有 HTTP 和 HTTPS 端点的 Azure 云服务(使用 Node.js)。诀窍是让 IIS 为您处理 SSL 终止,以便您的 Node.js 应用程序仅侦听 HTTP(使用 process.env.PORT)。

我已将证书上传到 Windows Azure 门户,然后我的 ServiceDefinition.csdef 文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="my-cloud-service-name" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="my-cloud-service-name" vmsize="Small">
    <Imports />
    <Startup>
      <Task commandLine="setup_web.cmd &gt; log.txt" executionContext="elevated">
        <Environment>
          <Variable name="EMULATED">
            <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
          </Variable>
          <Variable name="RUNTIMEID" value="node;iisnode" />
          <Variable name="RUNTIMEURL" value="http://az413943.vo.msecnd.net/node/0.8.4.exe;http://az413943.vo.msecnd.net/iisnode/0.1.21.exe" />
        </Environment>
      </Task>
      <Task commandLine="node.cmd ..\startup.js" executionContext="elevated" />
    </Startup>
    <Endpoints>
      <InputEndpoint name="Web" protocol="http" port="80" />
      <InputEndpoint name="WebSSL" protocol="https" port="443" certificate="my-certificate-name" />
    </Endpoints>
    <Certificates>
      <Certificate name="my-certificate-name" storeLocation="LocalMachine" storeName="CA" />
    </Certificates>
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Web" endpointName="Web" />
          <Binding name="WebSSL" endpointName="WebSSL" />
        </Bindings>
      </Site>
    </Sites>
  </WebRole>
</ServiceDefinition>

然后在我的 Web.cloud.config 文件的 iisnode 元素中,我确保提升 HTTPS 服务器变量:

<iisnode debuggingEnabled="false" devErrorsEnabled="false" loggingEnabled="false" node_env="production" promoteServerVars="HTTPS" />

这让我可以使用一些 Express.js 中间件设置 x-forwarded-proto 标头,该中间件是识别 HTTP 请求的原始协议的事实标准:http://en.wikipedia.org/wiki/List_of_HTTP_header_fields

exports.xForwardedProto = function(req, res, next) {
    if(!req.headers['x-forwarded-proto']) {
        if(req.headers['x-arr-ssl'] || req.headers['x-iisnode-https'] === 'on') {
            req.headers['x-forwarded-proto'] = 'https';
        }
    }

    next();
};

然后,当我想将 HTTP 请求重定向到 HTTPS 时,我会使用 Express.js 中间件:

exports.httpsOnly = function(req, res, next) {
    if(req.protocol === 'http' && process.env.NODE_ENV && process.env.NODE_ENV != 'development') {
        return res.redirect(301, 'https://' + req.get('host') + req.url);
    }

    next();
};

【讨论】:

  • 这是一个旧答案。只是补充。正如提到的here,现在有一种更好的方法可以在 azure 网站上强制执行 HTTPS
猜你喜欢
  • 1970-01-01
  • 2017-01-18
  • 2016-01-07
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 2012-07-14
相关资源
最近更新 更多