authentication - 如何正确获取由前端设置的 kubernetes 集群中的服务发出的 cookie?

标签 authentication cookies kubernetes jelastic hasura

情况如下:我有一堆应用程序要部署到我的 k8s 集群:

  • hasura 后端(暴露于 nginx 入口)
  • 托管在 openfaas 实例上的一些无服务器功能
  • 身份验证服务
  • 在 nginx docker 镜像上提供的 vuejs 前端应用程序(通过 nginx 入口公开)

  • 我的 kubernetes 集群托管在 Jelastic 上。我在集群前面使用 nginx 负载均衡器启用了 SSL:
    enter image description here
    在我的集群内部,我有通常的 nginx-ingress-controller。
    现在,我正忙于尝试正确实现身份验证。关注 this advice ,这就是我正在做的事情:
  • 我在集群内部署了一个身份验证服务器 (fusionauth),服务类型为 ClusterIP
  • 我有一个执行用户登录的 openfaas 函数:它接受用户名、密码和应用程​​序 ID;它返回一个 JWT 并发出一个 session cookie;该函数与 fusionauth 对话并获取 JWT 和刷新 token
  • 我有一个hasura行动login调用 login openfaas 函数
  • 我有一个调用 hasura 操作的前端应用程序 login

  • 基本上,我的前端由 k8s 集群上的 nginx docker 镜像提供服务,与 hasura api 对话,后者与内部 openfaas 登录功能对话,后者与内部 fusionauth 对话。前端和 hasura api 都定义了一个入口:
    kind: Ingress
    apiVersion: extensions/v1beta1
    metadata:
      name: admin-ui
      namespace: services-108-staging
      labels:
        app.kubernetes.io/instance: admin-ui
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/name: admin-ui
        app.kubernetes.io/version: '0.0'
        helm.sh/chart: admin-ui-0.0.0
      annotations:
        meta.helm.sh/release-name: admin-ui
        meta.helm.sh/release-namespace: services-108-staging
        nginx.ingress.kubernetes.io/configuration-snippet: |
          more_set_headers "Access-Control-Allow-Origin: $http_origin";
        nginx.ingress.kubernetes.io/cors-allow-credentials: 'true'
        nginx.ingress.kubernetes.io/cors-allow-methods: 'PUT, GET, POST, OPTIONS'
        nginx.ingress.kubernetes.io/enable-cors: 'true'
    spec:
      rules:
        - host: admin-staging.my-env.the-jelastic-host.com
          http:
            paths:
              - path: /
                backend:
                  serviceName: admin-ui
                  servicePort: 4000
    ---
    kind: Ingress
    apiVersion: extensions/v1beta1
    metadata:
      name: api
      namespace: services-108-staging
      labels:
        app.kubernetes.io/instance: api
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/name: api
        app.kubernetes.io/version: '0.0'
        helm.sh/chart: api-0.0.0
      annotations:
        kubernetes.io/ingress.class: nginx
        meta.helm.sh/release-name: api
        meta.helm.sh/release-namespace: services-108-staging
    spec:
      rules:
        - host: api-staging.my-env.the-jelastic-host.com
          http:
            paths:
              - path: /
                backend:
                  serviceName: api
                  servicePort: 8080
    
    只有前端的 nginx 负载均衡器可以访问 admin-staging.my-env.the-jelastic-host.comapi-staging.my-env.the-jelastic-host.com网址。这两个应用程序通过其他域上的前端负载均衡器提供服务,例如 admin-staging.my-host.comapi-staging.my-host.com分别。前端负载均衡器像这样重新路由其传入请求(例如,对于 admin-staging url):
    server {
      server_name admin-staging.my-host.com;
    
      listen 443 ssl;
    
      [...]
      
      location / {
        [...]
        proxy_pass http://admin-staging.my-env.the-jelastic-host.com;
      }
    }
    
    我的目标是让 session cookie 存储在我的前端应用程序中。目前,虽然我得到 Set-Cookie调用 login 时的 header graphql 突变:
    enter image description here
    我没有在我的前端应用程序的 cookie 中得到它:
    enter image description here
    我不知道我应该设置什么来让 session cookie 出现在我的前端存储中。一切都通过 https 提供:hasura api 和前端应用程序。我应该设置一个特定的domain在我的 cookies 里? cookie 是从 k8s 集群内部发出的,来自我托管的无服务器功能
    auth.services-108-staging.svc.cluster.local
    
    (这是 .Net Core 调用 Request.Host.ToUriComponent() 的结果)。我应该在我的 cookie 中设置一个特定的域吗?我应该设置session affinity ?我应该在哪个入口定义 session 亲和性?这足以在我的集群中定义 session 亲和性吗?我的集群前面的 nginx 负载均衡器呢?本质上,负载均衡器将请求路由到 k8s 集群。我必须在那里设置一些特别的东西吗?

    最佳答案

    看起来 session 亲和性是首先尝试的不错选择。
    您能否尝试在所有入口规则中添加以下注释并检查是否可以帮助您解决问题?

    nginx.ingress.kubernetes.io/affinity     cookie
    nginx.ingress.kubernetes.io/affinity-mode   persistent
    nginx.ingress.kubernetes.io/session-cookie-name hasura-backend
    nginx.ingress.kubernetes.io/session-cookie-change-on-failure    true
    
    或者,您可以尝试消除 https2http 终止,这很可能是您的 FE 应用程序看不到 cookie 的原因。
    在屏幕截图中,可以看到 Set-Cookie header 设置了安全标志。为了消除 SSL 终止,您可以将公共(public) IP 地址附加到您的 K8s 工作节点,然后在入口中激活 SSL 注释并与您的前端建立直接的 https 连接。

    关于authentication - 如何正确获取由前端设置的 kubernetes 集群中的服务发出的 cookie?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62554763/

    相关文章:

    ios - 在 viewController 之间传递 facebook 信息

    javascript - 如何从angularjs中的响应 header 读取 token

    Python-手动浏览器登录后从urllib2恢复网络 session

    Javascript cookie 不适用于表单提交

    php - 在 Kohana 3 中设置 cookies 盐的正确方法是什么?

    amazon-web-services - 无法为 nlb 提供静态 IP

    java - 如何连接到现有的 kubernetes 服务器并使用 java 列出所有 pod?

    php - 登录和注销系统问题

    node.js - [Express][Nodejs] 如何在 socket.io 连接期间解密 express-session cookie?

    azure - Terraform Force 在 "terraform plan"期间替换了 AKS 集群