【问题标题】:How do you force express on node.js in Azure Websites to use https?如何强制 Azure 网站中 node.js 上的 express 使用 https?
【发布时间】:2013-12-14 00:28:11
【问题描述】:

在 Windows Azure 网站上运行,我想通过默认的 *.azurewebsites.net 证书使用 ssl。它无需执行任何操作即可工作,但 http 也可用于每个目的地,而不仅仅是 https。如何强制从 http 重定向到 https?通常我可以这样做:

var https = require('https');

...

var options = {
      key: fs.readFileSync('path.key'),
      cert: fs.readFileSync('path.crt')
    };

...

https.createServer(options, app)

但由于我对 *.azurewebsites.net 证书一无所知,例如它的路径,所以这行不通。

如何将所有或部分请求重定向到 https?

【问题讨论】:

    标签: node.js ssl https express azure-web-app-service


    【解决方案1】:

    web.config 中,在具有stopProcessing="true" 的任何其他规则之前添加以下规则。

    <rule name="RedirecttoHTTPS">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
        <add input="{URL}" pattern="/$" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
      </conditions>
      <action type="Redirect" url="https://{SERVER_NAME}/{R:1}" redirectType="SeeOther" />
    </rule>
    

    如果您想要 *.azurewebsite.net 通配符证书,也可以只使用普通的 http.createServer(app) 进行生产。

    参考资料:

    1. How to require SSL in IIS7 and Azure with Rewrite
    2. URL Rewrite Module Configuration Reference

    【讨论】:

    • 这是可行的,但会在浏览器上打开 app.js 文件。有什么想法吗?
    【解决方案2】:

    接受的答案对我不起作用,它只会显示一个空白页,这个:

    <!-- Redirect all traffic to SSL -->
        <rule name="Force HTTPS" enabled="true">
          <match url="(.*)" ignoreCase="false" />
          <conditions>
            <add input="{HTTPS}" pattern="off" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
        </rule>
    

    来自https://gist.github.com/tstpierre/afec7eb409aebe0bf3d1 的工作完美。

    【讨论】:

    • 这可行,但它会在浏览器上打开我的 app.js 文件。有什么想法吗?
    【解决方案3】:

    如果您希望验证您的节点应用程序是否从节点应用程序内接收安全流量,Richard Astbury 有一个solution on his blog

    tl;dr:IIS 充当节点应用程序的代理,如果通过 HTTPS 提供请求,则向请求添加“x-arr-ssl”标头。您还可以使用“x-site-deployment-id”标头来验证您的应用当前是否在 azure 中运行。中间件最终是这样的:

    function requireHTTPS(req, res, next) {
        var isAzure = req.get('x-site-deployment-id'),
            isSsl = req.get('x-arr-ssl');
    
        if (isAzure && !isSsl) {
            return res.redirect('https://' + req.get('host') + req.url);
        }
    
        next();
    }
    
    app.use(requireHTTPS);
    

    当您使用它时,最好也添加 HSTS:

    var helmet = require('helmet');
    
    function requireHTTPS(req, res, next) {
        var isAzure = req.get('x-site-deployment-id'),
            isSsl = req.get('x-arr-ssl');
    
        if (isAzure && !isSsl) {
            return res.redirect('https://' + req.get('host') + req.url);
        }
    
        next();
    }
    
    app.use(requireHTTPS);
    app.use(helmet.hsts({
        maxAge: 10886400000,     // Must be at least 18 weeks to be approved by Google
        includeSubdomains: true, // Must be enabled to be approved by Google
        preload: true
    }));
    

    当然,您可以随时与 web.config 答案一起执行此操作。

    【讨论】:

      【解决方案4】:

      由于听起来 Azure 网站在您的情况下充当反向代理,因此此方法可能适合您:

      如果您可以从以下获取协议,它应该会对您有所帮助:

      req.headers['x-forwarded-proto']
      

      如果它对您所服务的资源无效,这应该为您提供需要键入的 http 或 https 以便进行重定向。

      每当我收到请求时,我都会使用以下代码进行重定向(例如,对于 html 文件或站点根目录)。我将所有我想保护的文件放在 /secure 目录中,以便于知道什么应该和不应该是 ssl:

      protocol = req.headers['x-forwarded-proto'];
      
      if ((req.url.lastIndexOf('.html') == (req.url.length - 5)) || (req.url.slice(-1) == '/')) {
          if (protocol == 'http') {
      
              if (req.url.indexOf('/secure/') == 0) {
                  console.log('Non ssl request made to secure resource: ' + req.url);
                  console.log('Redirecting to https://' + site_host_name + req.url);
                  res.writeHead(301,
                      {Location: 'https://' + site_host_name + req.url}
                  );
                  res.end();
                  return;
              } else {
                  next();
                  return;
              }
          } else {
              if (req.url.indexOf('/secure/') != 0) {
                  console.log('ssl request made for non-secure resource: ' + req.url);
                  console.log('Redirecting to http://' + site_host_name + req.url);
                  res.writeHead(301,
                      {Location: 'http://' + site_host_name + req.url}
                  );
                  res.end();
                  return;
              } else {
                  next();
                  return;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-01-31
        • 2020-06-29
        • 1970-01-01
        • 2020-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-09
        • 2015-02-27
        相关资源
        最近更新 更多