【问题标题】:Running ReactJS application with HTTPS and backend APIs behind a Kubernetes Ingress在 Kubernetes Ingress 后面使用 HTTPS 和后端 API 运行 ReactJS 应用程序
【发布时间】:2020-08-24 09:13:00
【问题描述】:

我正在开发一个调用在 kubernetes 中运行的 REST API 的 ReactJS 应用程序。 设置如下:

  • ReactJS 在本地开发/调试并使用“npm start”运行,因为没有什么能比本地开发服务器检测更改并在检测到更改时重新加载浏览器的速度更快。
  • ReactJS API 请求使用 axios 完成
  • 用 GO 编写的后端 API 在 minikube 本地作为单独的部署/服务运行。
  • 在 minikube 中本地安装了一个 Ingress,用于将来自 urlshortner.local 的请求转发到相应的 k8s 服务。

基本思路如下:

ReactJS -> k8s 入口 -> GO REST API

现在,当我尝试设置安全的 httpOnly cookie 时,问题就开始了。因为 cookie 需要是安全的,所以我创建了一个自签名 ssl 证书并将其应用到入口处使用。我还在入口配置中启用了 CORS 设置。我还将 axios 配置为不拒绝自签名证书。

由于某些我不知道的原因,我无法成功提出请求。

下面是我的相关配置文件和代码sn-ps:

k8s 入口:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: url-shortner-backend-services
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://localhost:4000"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
spec:
  tls:
    - secretName: urlshortner-local-tls
      hosts:
        - urlshortner.local
  rules:
    - host: urlshortner.local
      http:
        paths:
          - path: /shortner(/|$)(.*)
            backend:
              serviceName: url-shortener-service
              servicePort: 3000
          - path: /auth(/|$)(.*)
            backend:
              serviceName: auth-service
              servicePort: 3000

react 应用启动脚本:

PORT=4000 SSL_CRT_FILE=tls.crt SSL_KEY_FILE=tls.key react-scripts start

创建用于发出POST请求的axios实例的axios代码sn-p

import axios from "axios";
import https from "https";

export default axios.create({
    baseURL: 'https://urlshortner.local',
    withCredentials: true,
    httpsAgent: new https.Agent({
        rejectUnauthorized: false
    })
});

发出 POST 请求时,我在浏览器控制台/网络选项卡中看到以下错误,即使当我第一次加载页面时,我接受了证书警告并将其添加为受信任的证书:

我想要达到的最终结果是能够设置 cookie 并在后续请求中读取 cookie。

cookie 设置如下:

c.SetSameSite(http.SameSiteNoneMode)
c.SetCookie("token", resp.Token, 3600, "/", "localhost:4000", true, true)

缺少什么?我究竟做错了什么? 提前致谢

【问题讨论】:

    标签: reactjs ssl kubernetes axios cors


    【解决方案1】:

    我终于设法解决了这个问题,好消息是您不需要创建自签名证书。

    步骤如下:

    1. 在启动您的开发反应服务器之前设置一个 HOST 环境变量。
    2. 调整 /etc/hosts 使 127.0.0.1 指向 HOST 环境变量中设置的值
    3. 调整您的 k8s 入口 CORS 设置,以允许来自 HOST 环境变量中设置的域的“cors-allow-origin”
    4. 现在设置 cookie 应该可以正常工作了。

    下面是相关代码sn-ps:

    • npm 启动脚本
    
          "scripts": {
            "start": "PORT=4000 HOST=app.urlshortner.local react-scripts start",
          }
    
    

    注意HOST环境变量,PORT环境变量是可选的,我使用它是因为默认端口3000已经被占用了。

    • /etc/hosts
    
        127.0.0.1       app.urlshortner.local
        192.168.99.106  urlshortner.local
    
    

    注意 192.168.99.106 是我的本地 minikube ip 地址。

    • Kubernetes 入口配置
    
        apiVersion: networking.k8s.io/v1beta1
        kind: Ingress
        metadata:
          name: url-shortner-backend-services
          namespace: default
          annotations:
            nginx.ingress.kubernetes.io/rewrite-target: /$2
            nginx.ingress.kubernetes.io/enable-cors: "true"
            nginx.ingress.kubernetes.io/cors-allow-origin: "http://app.urlshortner.local:4000"
            nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
        spec:
          rules:
            - host: urlshortner.local
              http:
                paths:
                  - path: /shortner(/|$)(.*)
                    backend:
                      serviceName: url-shortener-service
                      servicePort: 3000
                  - path: /auth(/|$)(.*)
                    backend:
                      serviceName: auth-service
                      servicePort: 3000
    
    

    这里重要的是:

    
        nginx.ingress.kubernetes.io/enable-cors: "true"
        nginx.ingress.kubernetes.io/cors-allow-origin: "http://app.urlshortner.local:4000"
        nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    
    
    • 已使用 axios 实例
    
        import axios from "axios";
        
        let baseURL = '';
        if (process.env.NODE_ENV === 'development') {
            baseURL = 'http://urlshortner.local';
        }
        
        export default axios.create({
            baseURL,
            withCredentials: true
        });
    
    
    • cookie 的设置方式:
    
        c.SetCookie("token", resp.Token, 3600, "/", ".urlshortner.local", false, true)
    
    

    注意使用的域。它以“。”开头

    我希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2019-05-14
      • 2022-10-15
      • 1970-01-01
      • 2020-04-29
      • 1970-01-01
      • 2018-03-12
      • 2018-09-30
      • 2020-05-13
      • 1970-01-01
      相关资源
      最近更新 更多