首页 > 解决方案 > Next.js 将 api 限制为我的 next.js 应用程序和我的移动应用程序

问题描述

让我澄清一下我的用例:

我有一个 next.js 应用程序,它是一个用于列出房地产对象的平台。我有几个我在 next.js 应用程序中使用的 api 路由。例如:

/api/createpost -> 

从我的 next.js 应用程序上的表单中获取信息并创建一个数据库条目以执行新帖子

/api/getposts -> 

从我的数据库中获取所有房地产帖子并显示它

/api/login -> 

通过检查数据库中的凭据登录用户并发送 jwt

/api/register -> 

通过从我的 next.js 应用程序的表单中获取凭据、注册用户并在我的数据库中创建一个条目来注册用户


现在,为了保护我的 api,我想确保检查是否存在有效的用户会话,如果有人正在调用其中一个 api(注册/登录 api 除外)以获得预期的结果。我通过调用/api/login路由并获得有效的用户会话来做到这一点。直到这里一切正常。/api/createpost只有当我们有一个有效的用户会话时,才能调用类似的 API 。

现在我想创建一个移动应用程序,并且我想使用上面的 api 路由在我的移动应用程序中提供完整的功能。它应该工作相同,例如,如果我想/api/createpost在我的移动应用程序上调用,我需要一个有效的用户会话。

但是我想通过在我的数据库中请求一个指向我的应用程序的密钥来限制我的 api,并说如果你调用/api/createpostapi 可以,首先我需要验证它是移动应用程序在询问。然后,移动应用程序将在请求中提供密钥。

我还没有尝试过,但我认为它应该可以工作。现在大混乱:如果我们调用/api/createpost并且 api 想要一个有效的令牌来签入数据库,这将适用于移动应用程序,因为我们给它一个有效的令牌来签入数据库,我们如何提供一个令牌如果我们从 next.js 应用程序中调用 api?由于我必须在客户端进行 api 调用,因此我无法提供密钥或其他东西来验证调用是否来自我的 next.js 应用程序。

标签: next.js

解决方案


如果您的应用程序是私有的

(仅供您或少数选定的人使用)您可以通过 SSL 将私有 API 密钥与从您的应用程序到服务器的每个请求一起发送并验证它。或者,您可以将 API 限制为仅接受来自特定 IP 的请求。

如果您的申请是公开的

不幸的是,无法确定请求的来源,因为您的应用可以发送任何内容,攻击者可以手动发送。
想一想,如果您的应用程序试图向您的 API 发出请求,任何用户都可以在此请求发送出他/她的机器之前拦截该请求,并从同一台机器上的不同应用程序发送完全相同的请求。

你可能会说,我可以加密请求和响应,这样攻击者就没有用了。但是这样的加密将需要一个已经商定的密钥,或者在每个会话开始时提供一个新密钥的某种方式。

  1. 如果密钥已经被商定,则应用程序必须包含它,正如您在问题中已经猜到的那样,无论您尝试如何隐藏它,攻击者都可以检索此密钥。
  2. 如果加密密钥是在每个会话开始时提供的新密钥,这几乎就是 SSL 的工作方式,您的浏览器会处理此事务。您的服务器向您的浏览器发送一个公钥来加密请求,然后服务器可以使用私钥解密该请求。在这种情况下,您又回到了同样的问题,您如何验证您向谁提供了加密密钥?什么会阻止攻击者请求加密密钥?

必须有某种方法可以设计出不需要此限制的应用程序。我认为您应该问的问题不是如何将您的 api 限制为某个应用程序,而是如何设计不需要此限制的应用程序。 如果您能告诉我们您为什么需要此限制,我们可能会为您提供帮助。


更新

实际上有一种方法可以验证请求是否来自您的应用程序,而不是使用 api 密钥。

对于 Webapps
您可以使用 Google 的reCAPTCHA来验证您/register和“/login”路由上的用户,并在成功的验证码响应时提供访问令牌或启动有效的用户会话。使用 reCAPTCHA v3,您甚至可以在不打扰用户的情况下验证每个用户操作。这消除了我在上面的回答中提到的两个问题 -

  1. 您不必将 api 密钥存储到应用程序/网络应用程序中。
  2. 该请求不能被欺骗,因为它需要在您的应用程序中进行人工用户交互。验证码验证成功将从 Google 的 reCAPTCHA 服务器而不是您的客户端应用程序到达您的 API。此通信将使用 Google 与您共享的预先调解的私有 API 密钥进行身份验证,其工作方式与您验证外部域的方式相同。

对于安卓应用

实现相同目的的类似方法是通过Android SafetyNet Attestation API。这会检查运行时环境并使用您的应用提供 SafetyNet API 的动态生成的随机数对响应进行签名。请仔细阅读其文档以了解如何在使用此 API 时创建潜在的安全漏洞以及如何避免这些漏洞。

对于 iOS 应用,
DeviceCheck的工作方式与此类似,只是设备有效性由 Apple 服务器提供给您。


推荐阅读