如何为Nginx-Ingress配置基于Go认证API的外部中间件
问题描述
我用Go写了一套认证API,包含以下功能:
- POST /register:创建新用户并存储到Postgres数据库
- POST /login:验证凭据后生成会话令牌并附加到Cookie,同时在Redis中创建会话记录
- GET /logout:从Redis删除令牌并使Cookie过期以注销会话
这套API已经部署在Kubernetes集群中,有独立的Deployment、Service和Ingress。
另外我有一个名为foo的服务,它的Ingress配置如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: "foo" spec: tls: - hosts: - "foo.domain.com" rules: - host: "foo.domain.com" http: paths: - path: "/" pathType: Prefix backend: service: name: "foo" port: number: 5050
我希望给这个Ingress配置类似中间件的机制,让每次访问foo.domain.com时,请求先转发到我的Go认证API验证Cookie的有效性,再决定是否允许访问。我是Kubernetes新手,想知道这是否可行?还是需要用其他方案?
之前我找到一篇相关帖子,里面的配置是:
annotations: nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth" nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
但这个配置看起来只适用于OAuth2场景,而我并没有用OAuth2。
解决方案
1. 用Nginx Ingress的认证注解即可(完全适配你的场景)
你看到的auth-url注解并不是只针对OAuth2,它是Nginx Ingress提供的通用认证机制,只要你的Go认证API满足以下简单要求就能用:
- 接收Ingress转发来的请求(会包含用户的Cookie)
- 验证Cookie中的会话令牌是否有效(去Redis查记录)
- 验证通过返回2xx状态码,验证失败返回4xx/5xx状态码
修改后的foo服务Ingress配置示例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: "foo" annotations: # 指向你的认证API的集群内部Service地址和验证接口 nginx.ingress.kubernetes.io/auth-url: "http://auth-service.default.svc.cluster.local/verify" # 验证失败时跳转的登录页面(可选,根据需求调整) nginx.ingress.kubernetes.io/auth-signin: "https://foo.domain.com/login?redirect=$escaped_request_uri" spec: tls: - hosts: - "foo.domain.com" rules: - host: "foo.domain.com" http: paths: - path: "/" pathType: Prefix backend: service: name: "foo" port: number: 5050
关键说明:
- 你需要给认证API新增一个
/verify接口,专门处理Ingress转发的认证请求,逻辑就是提取Cookie中的令牌、查询Redis验证有效性 auth-url中的地址要改成你的认证API在集群内的Service地址(格式通常为http://<service-name>.<namespace>.svc.cluster.local)auth-signin是可选配置,验证失败时Ingress会自动跳转到指定的登录页面,同时携带原请求地址,方便登录后跳转回去
2. 替代方案(当Ingress注解满足不了复杂需求时)
如果你的认证逻辑涉及复杂的请求改写、多维度权限校验等场景,可以考虑以下方案:
- 服务网格(如Istio):用Istio的
AuthorizationPolicy结合自定义认证服务,实现更细粒度的流量控制和认证逻辑 - Sidecar模式:给
foo服务的Pod添加一个Sidecar容器(比如自己用Go写的轻量认证代理),所有请求先经过Sidecar验证,再转发到主服务 - 服务内部集成:在
foo服务代码里直接调用认证API做验证,但这种方式耦合度高,不推荐
内容的提问来源于stack exchange,提问作者gKits
相关产品推荐
相关产品推荐

