我对Spring MVC控制器范围和REST服务有疑问。我有几个REST服务,它在响应中返回一个令牌,以便稍后我可以重新创建应用程序的状态,但我不希望用户使用相同的令牌两次,所以我决定保存一个唯一的标识符在令牌内部以及HttpServletRequest中,所以我可以在收到请求时检查它(在每个请求中生成一个新的标识符)。
所以,我的问题是:
)1)有没有其他方法可以确保某些用户不会多次使用相同的令牌(也被认为是在DB中保存该标识符,但我会有很多查询要插入,删除,验证等。)2)接收请求的控制器是单例,还是原型? (考虑到标识符来自会话,我不想在不同的会话之间混合)。
答案 0 :(得分:1)
无法实现它 没有在某处保留令牌的轨道。此安全架构需要进行一些权衡,处理它。
为用户提供一个令牌并在服务器端保持跟踪,就像白名单一样:
403
等正确的状态代码来拒绝该请求。另外,请考虑为令牌分配到期日期,并拒绝任何带有过期令牌的服务器请求。
关于您的表现问题:请记住premature optimization is the root of all evil。在您遇到性能问题并且已证明表明性能问题来自您存储令牌的方式时,您不应该进行优化。例如,您可以开始将令牌存储在数据库中,然后考虑内存中的缓存。但是在修复你目前没有的问题时要小心。
如果你选择JWT,有一些Java库可以发布和验证JWT令牌,例如:
jti
声明应该用于在令牌上存储令牌标识符。验证令牌时,请通过检查服务器端的令牌标识符jti
声明的值来确保其有效。
对于令牌标识符,您可以使用UUID。在Java中,它很简单:
String uuid = UUID.randomUUID().toString();
答案 1 :(得分:0)
由于HttpSession#getId()是唯一的,因此您可以使用它来创建唯一标记:
// pseudo code
String token = httpSession.getId() + "-" + System.currentTimeMillis();
您也可以创建自己的计数器。
答案 2 :(得分:0)
这是我防止它的两种技术
禁用提交按钮: 我们可以在函数调用 HTTP 请求之前禁用提交按钮,并在完成获得 HTTP 响应后再次启用它。这种技术对于需要很长时间才能完成的过程(超过 5 秒)是有效的。由于急于获得结果,用户无法再次单击 n' click。此外,我们可能会展示一个加载框以获得良好的体验。
发出请求令牌/ID: 这种技术实际上更复杂,更难实现,但得益于良好的框架(如 Spring Boot)使这更容易。在进入代码实现之前,先说一下机制; 当表单页面加载时,发出一个新的 requestId 在调用后端服务之前将发出的 requestId 放入 HTTP 标头 后端服务识别 requestId 是否已经注册 如果 requestId 已经注册,那么我们可以标记为违规请求