【问题标题】:How to secure client app (react) and API communication如何保护客户端应用程序(反应)和 API 通信
【发布时间】:2018-08-26 09:21:35
【问题描述】:

我有一个客户端 React 应用程序和一个 Rails API,React 应用程序从中获取数据。

如您所料,我只希望我的 React 应用程序能够从 API 获取数据,而世界其他地方不应该能够从它接收数据。

尽管进行了很多搜索,但我仍未找到确保两个应用程序之间通信安全的最佳方式。

我已经阅读了有关 JWT 令牌和基于 cookie 的会话身份验证的文章,但大多数文章似乎都侧重于用户身份验证(即登录/注销),而不仅仅是两个应用程序之间的通信。

这两个应用程序将共享同一个域,那么依靠 Cross Origin 来保护通信就足够了吗?

任何建议都将不胜感激。

【问题讨论】:

  • 嘿。您最终使用的方法是什么?我也有点担心任何人都可以使用 chrome 开发工具剖析我的 API。最好将 api 通信也加密。

标签: ruby-on-rails node.js reactjs api authentication


【解决方案1】:

如果我的问题是正确的,您希望您的客户端(React 应用程序)成为唯一可以访问您的服务器的客户端。

作为解决方案,您必须结合使用 CORS 和 JWT 授权,因此我建议使用严格的 CORS 以仅启用您的 react 应用程序的域来调用服务器。为了实现这一点,我通常在我的服务器上使用CORS npm 模块和configure 源,或者你也可以自己做。

var express = require('express')
var cors = require('cors')
var app = express()

var corsOptions = {
  origin: 'http://example.com',
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 
}

上面的代码只允许服务器接受来自 example.com 的请求,或者查看this code 以获得更动态的白名单和黑名单方法。

现在回到 JWT,它只是一个 json 加密和解密令牌,可以跨 API 请求共享以进行身份​​验证以及授权用户。

例如,您可以在 JWT 中存储用户的电子邮件、角色和昵称等信息,并在每个 API 请求中发送此加密的 JWT,服务器授权此请求,如果为 true,则转发到请求的 API。这种授权和转发过程通常使用“拦截器”模式实现,其中中间件(Passport oAuth)在每次 API 调用之前进行检查和验证。


执行上述 2 件事将确保只有具有有效 JWT 令牌和您允许与服务器通信的域地址的客户端。这个客户端将是你的反应应用程序,因为它是唯一具有正确 JWT 和源地址的应用程序。

因此,现在您的 react 应用程序应该确保在 API 调用(post/get/put)中传递了适当的 JWT 令牌,很可能在 API 请求的标头中,您可以拥有一个 API 助手服务来执行此操作为您将其导入组件中,无论您在哪里进行 API 调用。并且您的节点服务器将实现护照中间件模式来授权此 JWT 并过滤未授权的请求。

如果您的 react 应用没有登录名,则 JWT 也可以是客户端 ID,它将您的客户端识别为合法。就像用户登录一样,您可以让应用程序使用秘密客户端 ID 等数据调用服务器。这将返回一个 JWT 令牌。或者您可以预先生成一个 JWT 令牌,并在它第一次加载时对应用程序存储作出反应,并通过设置 TTL 和另一个配置,您可以检查正在调用您的服务器的客户端是旧的还是新的或其他一些假客户。

HTH

【讨论】:

  • 感谢您的回复!为了让护照启动并运行,适当的设置是让我的前端(React)向它的后端(节点服务器)发出请求。然后,该后端会将护照作为中间件实现,并且仅在用户(即该应用程序)成功验证时才调用 API?
  • 是的,您的 React 应用程序应该确保在 API 调用(post/get/put)中传递了适当的 JWT 令牌。并且您的节点服务器将实现护照中间件模式来授权此 JWT 并过滤未授权的请求。
  • 在 chrome 开发工具等中查看请求时,JWT 令牌是否不可见?
  • 是的,会的,但是您可以为令牌设置到期时间(TTL)。如果用户试图复制它并从他的客户端进行 API 调用,我们的 CORS 应该处理它。
  • 这个答案不会阻止从另一个应用程序调用 API 端点。我可以启动 Postman 并向其中一个端点发出请求,服务器会愉快地响应。
【解决方案2】:

跨源域的情况是您可能需要实施 CORS 和黑名单等安全措施。 JWT 有点不同,正如您所说的那样对需要访问您的 api 的用户进行身份验证。

我相信只要您不在服务器上启用 CORS,就可以了。

请注意,这不会阻止人们做以下事情:

https://example.com/api/blah 访问您的 api 的一部分(如果它是公开的)。这与你的前端做同样的事情本质上是一样的,因为客户端是提供给用户的,然后用户可以完全控制客户端。他们可以将您应用程序中的所有 api 调用实例更改为不同的端点,而您无法阻止它们,就像他们可以在 url 栏中键入它一样。您的 api 上的任何公共端点都不得共享敏感信息。

【讨论】:

  • 感谢您的回复约翰。这是我面临的问题,我怎样才能确保只有来自我的前端应用程序的请求得到响应(即你不能只在浏览器中输入 URL)?以前人们可能使用过 API 密钥,但在客户端应用程序中存储它并没有完全安全的地方:)
  • 在这种情况下,您需要实施某种身份验证。 Jwts 经常被认为是很棒的,因为它们是无状态的,但是为了能够记录其他人,你需要保持一个状态。我更喜欢护照作为我的登录方式
  • 这两个答案如何阻止用户进入 DevTools,看到服务 API 并直接调用它?由于它全部来自用户浏览器的 JavaScript,这似乎仍然不安全..
猜你喜欢
  • 1970-01-01
  • 2020-10-24
  • 2014-03-16
  • 2019-12-19
  • 2018-03-21
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 2018-10-17
相关资源
最近更新 更多