authentication - 如何正确获取由前端设置的 kubernetes 集群中的服务发出的 cookie?
问题描述
情况如下:我有一堆应用程序要部署到我的 k8s 集群:
- 一个 hasura 后端(暴露在 nginx 入口处)
- 托管在 openfaas 实例上的一些无服务器功能
- 身份验证服务
- 在 nginx docker 映像上提供的 vuejs 前端应用程序(通过 nginx 入口公开)
我的 kubernetes 集群托管在 Jelastic 上。我在集群前面使用 nginx 负载均衡器启用了 SSL:
在我的集群内部,我有通常的 nginx-ingress-controller。
现在,我正忙于尝试正确实施身份验证。按照这个建议,这就是我正在做的事情:
- 我在集群内部署了一个身份验证服务器(fusionauth),服务类型为
ClusterIP
- 我有一个执行用户登录的 openfaas 函数:它接受用户名、密码和应用程序 ID;它返回一个 JWT 并发出一个会话 cookie;该函数与 fusionauth 对话并获取 JWT 和刷新令牌
- 我有一个
login
调用login
openfaas 函数的 hasura 动作 - 我有一个调用 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.com
和api-staging.my-env.the-jelastic-host.com
URL。这两个应用程序分别通过其他域上的前端负载均衡器提供服务,例如admin-staging.my-host.com
和api-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;
}
}
我的目标是让会话 cookie 存储在我的前端应用程序中。目前,虽然我Set-Cookie
在调用login
graphql 突变时得到了标题:
我没有在我的前端应用程序的 cookie 中得到它:
我不知道我应该设置什么来让会话 cookie 出现在我的前端存储中。一切都通过 https 提供:hasura api 和前端应用程序。domain
我应该在我的 cookie 中设置一个特定的值吗?cookie 是从 k8s 集群内部发出的,来自我托管的无服务器功能
auth.services-108-staging.svc.cluster.local
(这是 .Net Core 调用的结果Request.Host.ToUriComponent()
)。我应该在我的 cookie 中设置一个特定的域吗?我应该设置会话亲和力吗?我应该在哪个入口定义会话亲和性?这足以在我的集群中定义会话亲和性吗?我的集群前面的 nginx 负载均衡器呢?本质上,负载均衡器将请求路由到 k8s 集群。我必须在那里设置一些特别的东西吗?
解决方案
看起来会话亲和性是首先尝试的不错选择。
您能否尝试在所有入口规则中添加以下注释并检查是否可以帮助您解决问题?
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 标头设置了安全标志。为了消除 SSL 终止,您可以将公共 IP 地址附加到 K8s 的工作节点,然后在入口中激活 SSL 注释并与您的前端建立直接的 https 连接。
推荐阅读
- php - php 表值显示不正确
- matlab - 在气候数据运算符中使用 timeselavg 时出错
- java - 如何逐渐加快 Android 中的声音播放速度?
- powershell - PSScriptAnalyzer 在我的 Visual Studio 代码中不起作用
- java - 为什么builder会丢失类型?
- qt - Why expanding in QTreeView may work incorrectly?
- mongodb - Create MongoDB External View using SparkSQL Only
- crash - How to check if @EnvironmentObject is set? (SwiftUI)
- windows - GNU make directory listing using $(shell dir ) command
- jinja2 - Access Pelican page and article metadata the same way?