【问题标题】:Securing the Backend API Endpoints (MERN Application)保护后端 API 端点(MERN 应用程序)
【发布时间】:2023-03-19 17:17:01
【问题描述】:

我使用 MERN 制作了一个全栈 Web 应用程序,并使用 Kubernetes 集群进行部署。

应用程序运行良好,除了一个问题。也就是说,我(作为用户)能够从浏览器访问 API,例如 www.domain-name/api/orders 这给了我 JSON 响应.

这是我不想要的。我需要隐藏/限制它。

我正在使用 NGINX-INGRESS 进行路由:

apiVersion: extensions/v1beta1
kind: Ingress
metadata: 
    name: ingress-service 
    annotations: 
        kubernetes.io/ingress.class: nginx 
        nginx.ingress.kubernetes.io/use-regex: 'true'
spec: 
    rules: 
        - host: shopify.dev 
          http: 
            paths:
                - path: /api/users/?(.*) 
                  backend: 
                    serviceName: auth-srv 
                    servicePort: 3000
                - path: /api/orders/?(.*)
                  backend: 
                    serviceName: orders-srv
                    servicePort: 3000
                - path: /?(.*) 
                  backend: 
                    serviceName: client-srv
                    servicePort: 3000 

由于请求 /api 和 /*(前端)都是通过 nginx-ingress 路由的,这应该是这样工作的吗? 有什么办法解决这个问题?

【问题讨论】:

    标签: node.js docker kubernetes devops nginx-ingress


    【解决方案1】:

    您在浏览器中运行的客户端应用应该能够从 API 获取数据,因此很明显是您的应用发出请求还是您(作为用户)从相同的浏览器(或另一个 rest 客户端),它将通过(假设遵循相同的身份验证过程)。

    完全阻止它是不可能的,也不应该要求它,因为用户仍然可以访问相同的数据,无论是通过应用程序还是直接。

    但是,如果您想隐藏它,因为您不希望普通用户在期望一个漂亮的前端应用程序时看到一些奇怪的 json 响应(因为他们随机输入了一个不正确的 url?您不会故意将他们导航到应用程序中的此类端点),您可以将该逻辑实现到您的应用程序中。

    您可以这样做的方法是在您的前端应用程序发出的所有请求中包含一些自定义 HTTP 标头(在 axios/fetch 调用中),然后在您的支持上实现过滤逻辑,该逻辑将解析此标头以查看调用是从前端应用还是直接调用(可能是中间件,如果看到没有此标头的请求,会将用户重定向到根页面)。我以前用过这个解决方案,效果很好。

    但请再次注意,这与安全性无关,因为您的数据已经在您的前端应用程序中可用。此外,它与 kubernetes 本身无关,任何高级用户都可以伪造这样的请求来绕过这个解决方案。您的数据应该受到身份验证的保护,而不是某些 html 文档。

    例如,如果您使用axios,您可以为所有这样的请求全局设置该自定义标头(在前端)。

    axios.defaults.headers.common['fromApp'] = true 
    

    在你的后端,你可以创建一个中间件

    const isFrontendRequest = (req, res, next) => {
      const h = req.get('fromApp') // get the header
      if (!h) {
        // handle the request not originating from your app and return
      }
      next() // custom header was present if we are here, continue normally
    }
    

    然后您可以在每个传入请求之前全局应用它。

    app.use(isFrontendRequest)
    

    【讨论】:

    • 我阅读了大约 10 篇不同的博客/文章来理解这一点,但没有一个像你那样解释清楚。太感谢了。尊重!
    • 这正是我想要的。谢谢
    猜你喜欢
    • 2019-12-25
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 2020-11-30
    • 1970-01-01
    • 2020-05-29
    • 2020-10-24
    相关资源
    最近更新 更多