【问题标题】:Avoid REST service to be consumed twice避免两次使用 REST 服务
【发布时间】:2021-02-24 16:44:44
【问题描述】:

我有一个关于 Spring MVC 控制器范围和 REST 服务的问题。我有几个 REST 服务,它们在响应中返回一个令牌,以便我以后可以重新创建应用程序的状态,但我不希望用户两次使用相同的令牌,所以我决定保存一个唯一标识符在令牌内部以及 HttpServletRequest 中,所以我可以在收到请求时检查它(每个请求中都会生成一个新标识符)。 所以,我的问题是:

1) 是否有任何其他方法可以确保某些用户不会多次使用同一个令牌(也考虑将该标识符保存在数据库中,但我会有很多插入、删除、验证等查询)。
2)接收请求的控制器可以是单例,还是应该是原型? (考虑到标识符是从会话中获取的,我不想在不同的会话之间混用)。

【问题讨论】:

  • REST 和 HTTP 会话标识符在同一个句子中听起来不太好。
  • 我相信他的意思是 ajax。
  • 嗨@dit,实际上我通过ajax调用使用REST服务,但仍然是REST和HTTP会话
  • 我的想法和你一样@CássioMazzochiMolin,这就是为什么我要问任何其他方法,我不知道如何控制它
  • @maxivis 你不能同时拥有 REST 和 Http-Session,因为 REST = Session free。您只有带有 json 的 AJAX-Calls。

标签: spring rest httpsession


【解决方案1】:

关于只有效一次的令牌的几句话

这是不可能实现的 无需在某处跟踪令牌。这种安全架构需要一些权衡,处理它。

给用户一个令牌并在服务器端跟踪它,就像一个白名单

  • 发行令牌时,将其添加到白名单中。
  • 当请求带有令牌到达服务器时,检查白名单并:
    • 如果令牌有效,则接受请求并将令牌从白名单中删除。
    • 如果令牌无效,则通过返回适当的状态码(例如403)来拒绝请求。

另外,考虑为令牌分配一个过期日期,并拒绝任何带有过期令牌的服务器请求。

关于您的性能问题:请记住 premature optimization is the root of all evil。在您遇到性能问题并且您已经证明性能问题来自您存储令牌的方式之前,您不应该进行优化。例如,您可以开始将令牌存储在数据库中,然后考虑在内存中缓存。但在解决您目前没有遇到的问题时,请务必小心。

使用 JWT

如果您选择JWT,则有一些 Java 库可以发布和验证 JWT 令牌,例如:

jti 声明应用于将令牌标识符存储在令牌上。验证令牌时,请根据您在服务器端拥有的令牌标识符检查 jti 声明的值,以确保其有效。

对于令牌标识符,您可以使用UUID。在 Java 中,它很简单:

String uuid = UUID.randomUUID().toString();

【讨论】:

  • 嗨@CássioMazzochiMolin,谢谢你的回答,这就是我之前实现它的方式,但因为它意味着在数据库中写入令牌,然后读取它,如果它是正确的删除它,我自动假设它会导致我出现性能问题,但是你对过早的优化是正确的,我会给你+1这个概念,我会把这个问题再开放几天,以防其他用户有另一个建议。
  • 事实证明,至少在本地,使用 DB 方法的性能非常好,所以我放弃了这个实现。
【解决方案2】:

由于HttpSession#getId() 是唯一的,您可以使用它来创建唯一令牌:

// pseudo code
String token = httpSession.getId() + "-" + System.currentTimeMillis();

您也可以创建自己的计数器。

【讨论】:

  • 感谢@dit 的回复,但我的问题不是如何生成令牌,而是方法本身,我应该使用令牌(标识符)还是有其他方法?
【解决方案3】:

这是我防止它的两个技巧

  1. 禁用提交按钮: 我们可以在函数调用 HTTP 请求之前禁用提交按钮,并在完成获得 HTTP 响应后再次启用它。该技术对于需要很长时间才能完成(超过 5 秒)的过程非常有效。用户因为急于得到结果而不能再次点击n'click。此外,我们可能会展示一个加载框以获得良好的体验。

  2. 发出请求令牌/id: 这种技术实际上更复杂且难以实现,但得益于良好的框架(例如 Spring Boot)使这更容易。在进入代码实现之前,先说一下机制; 加载表单页面时,发出新的 requestId 在调用后端服务之前将发出的 requestId 放入 HTTP 标头 后端服务识别 requestId 是否已注册 如果 requestId 已经注册,那么我们可以标记为违规请求

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-29
    • 2013-03-14
    • 2021-12-14
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    相关资源
    最近更新 更多