How do you force express on node.js in Azure Websites to use https?

不羁岁月 提交于 2019-12-17 16:52:14

问题


Running on Windows Azure Websites, I want to use ssl via the default *.azurewebsites.net certificate. It works without doing anything, but http is also available for every destination, not just https. How do I force a redirect from http to https? Normally I could just do something like:

var https = require('https');

...

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

...

https.createServer(options, app)

but since I don't know anything about the *.azurewebsites.net certificate, such as its path, that's not going to work.

How do I redirect all or some requests to https?


回答1:


In web.config, add the following rule before any other rule that has 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>

You can also just use the normal http.createServer(app) for production if you want to the *.azurewebsite.net wildcard certificate.

References:

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



回答2:


The accepted answer wasn't working for me, it would just display a blank page, this one:

<!-- 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>

From https://gist.github.com/tstpierre/afec7eb409aebe0bf3d1 works perfectly though.




回答3:


If you prefer to validate that your node app is receiving secure traffic from within the node app, Richard Astbury has a solution on his blog.

tl;dr: IIS is acting as a proxy to the node app, and adds an "x-arr-ssl" header to requests if they were served over HTTPS. You can also use the "x-site-deployment-id" header to validate whether or not your app is currently running in azure. The middleware ends up like so:

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);

While you're at it, it's a good idea to add HSTS, too:

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
}));

Of course you can always do this in tandem with the web.config answer.




回答4:


Since it sounds like Azure Websites is acting as a reverse proxy in your case, this approch may work for you:

If you can get the protocol from the following, it should help you:

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

This should give you the http or https you need to key on on order to do a redirect if it is not valid for the resource you are serving.

I use code like the following to redirect any time I get a request (for an html file or site root for example). I put all the files I want to be secure in a /secure directory to make it easy to know what should and should not be 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;
        }
    }
}


来源:https://stackoverflow.com/questions/20578283/how-do-you-force-express-on-node-js-in-azure-websites-to-use-https

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!