MERN应用后端API端点安全防护问题求助
这是预期行为吗?
没错,这完全符合你当前Ingress配置的预期。你现在的Ingress规则只是单纯把匹配/api/...的请求转发到对应的后端服务,没加任何访问控制逻辑,所以任何人只要知道API路径,就能直接通过浏览器或者curl这类工具请求并拿到JSON响应——这是配置带来的结果,但显然不符合你的业务需求。
解决方法
下面给你几个实用的方案,你可以根据自己的场景选择:
1. 给API加密钥验证
在NGINX Ingress层面配置API密钥校验,只有携带有效密钥的请求才能访问API。比如可以通过Ingress的annotations来实现,让前端在请求API时统一带上指定的请求头,直接访问的话因为没带密钥会被拒绝:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-service annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/use-regex: 'true' # 自定义配置片段,校验X-API-Key请求头 nginx.ingress.kubernetes.io/configuration-snippet: | if ($http_x_api_key != "你的专属密钥") { return 403; }
记得把前端代码里的API请求都加上X-API-Key这个请求头,这样前端能正常调用,外部直接访问就会返回403。
2. 限制请求来源(只允许前端域名访问)
如果你的API只需要被自己的前端应用调用,可以通过校验请求的Origin或Referer头,只允许来自shopify.dev的请求访问API:
metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/use-regex: 'true' nginx.ingress.kubernetes.io/configuration-snippet: | if ($http_origin !~* "^https?://shopify.dev$") { return 403; }
不过要注意,这种方式是基础防护,Origin头是可以伪造的,适合不想改后端的快速场景,安全性不如身份验证。
3. 把API改成集群内部访问
如果你的API不需要对外暴露,只需要同集群内的前端服务调用,那可以把API服务设为ClusterIP(默认就是这个类型),然后让前端直接通过集群内部的服务名称访问API,同时移除Ingress里的/api路径规则。
比如前端代码里的API地址改成http://auth-srv:3000/api/users,这样外部完全碰不到API,从根源上解决问题。
4. 实现JWT身份验证
这是最安全的方案,适合需要用户登录才能访问API的场景。在你的Node.js后端添加JWT校验逻辑,用户登录后拿到令牌,之后所有API请求都必须携带这个令牌。没有有效令牌的请求直接返回401或403。
你可以用jsonwebtoken库在后端实现,或者用Kubernetes的认证服务(比如Keycloak)统一处理身份校验,这样即使有人知道API路径,没有登录后的有效令牌也拿不到数据。
内容的提问来源于stack exchange,提问作者Karan Kumar

