如何为 AWS Elb 后面的 reactJs SPA 重定向 http 到 https?

Posted

技术标签:

【中文标题】如何为 AWS Elb 后面的 reactJs SPA 重定向 http 到 https?【英文标题】:How to redirect http to https for a reactJs SPA behind AWS Elb? 【发布时间】:2018-01-12 21:23:08 【问题描述】:

如 create-react-app 用户指南的 deployment 部分所述,我选择使用 express 服务器进行部署。快速服务器设置在 EC2 实例上,并由 SSL 终止的 AWS Elb 前端。如何设置将 http 请求重定向到 https?

如果有解决方案,我也愿意使用 nginx

感谢任何帮助。

【问题讨论】:

【参考方案1】:

使用 npm:

npm install --save react-https-redirect

假设一个CommonJS环境,你可以简单的这样使用组件:

import HttpsRedirect from 'react-https-redirect';
class App extends React.Component 

  render() 
    return (
          <Providers>
            <HttpsRedirect>
              <Children />
            </HttpsRedirect>
           <Providers />
    );
  

【讨论】:

【参考方案2】:
const express = require('express');
const path = require('path');
const util = require('util');
const app = express();

/**
 * Listener port for the application.
 *
 * @type number
 */
const port = 8080;

/**
 * Identifies requests from clients that use http(unsecure) and
 * redirects them to the corresponding https(secure) end point.
 *
 * Identification of protocol is based on the value of non
 * standard http header 'X-Forwarded-Proto', which is set by
 * the proxy(in our case AWS ELB).
 * - when the header is undefined, it is a request sent by
 * the ELB health check.
 * - when the header is 'http' the request needs to be redirected
 * - when the header is 'https' the request is served.
 *
 * @param req the request object
 * @param res the response object
 * @param next the next middleware in chain
 */
const redirectionFilter = function (req, res, next) 
  const theDate = new Date();
  const receivedUrl = `$req.protocol:\/\/$req.hostname:$port$req.url`;

  if (req.get('X-Forwarded-Proto') === 'http') 
    const redirectTo = `https:\/\/$req.hostname$req.url`;
    console.log(`$theDate Redirecting $receivedUrl --> $redirectTo`);
    res.redirect(301, redirectTo);
   else 
    next();
  
;

/**
 * Apply redirection filter to all requests
 */
app.get('/*', redirectionFilter);

/**
 * Serve the static assets from 'build' directory
 */
app.use(express.static(path.join(__dirname, 'build')));

/**
 * When the static content for a request is not found,
 * serve 'index.html'. This case arises for Single Page
 * Applications.
 */
app.get('/*', function(req, res) 
   res.sendFile(path.join(__dirname, 'build', 'index.html'));
);


console.log(`Server listening on $port...`);
app.listen(port);

【讨论】:

谢谢,这比在你的 react 应用程序中安装另一个依赖项要好得多,这最终会增加包的大小【参考方案3】:

您最好的选择是将您的 ELB 配置为侦听 80 和 443 并将这些端口转发到您的 EC2 实例。然后,在您的 EC2 实例上,您可以运行 Nginx 并将其反向代理到在 localhost 上运行的快速服务器。你需要在你的 Nginx 配置中使用这个 -

server 
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;

您还可以找到一些与此相关的好帖子,例如我在下面链接的帖子。

https://www.nginx.com/resources/admin-guide/reverse-proxy/

https://www.bjornjohansen.no/redirect-to-https-with-nginx

【讨论】:

感谢您的回复。但是,我无需使用 nginx 就能实现解决方案。我在下面发布了解决方案,其中快递服务器本身处理重定向。

以上是关于如何为 AWS Elb 后面的 reactJs SPA 重定向 http 到 https?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 WebSocket 协议配置 AWS ELB 和 Nginx? [关闭]

如何为 ELB 实例安装外部 SSL?

如何为 AutoScale 实例使用 AWS 负载均衡器代理协议?

在 ELB 后面可访问的 AWS EB url

如何使 ChromeCast 与在 AWS ELB 后面运行的发送者应用程序一起工作

在 AWS ELB 后面使用嵌入式 Tomcat 的 Spring Boot - HTTPS 重定向