我有一个有关弹簧MVC控制器范围和REST服务的疑问。我有几个休息服务,wich返回响应中的令牌,以便以后重新创建应用程序的状态,但是我不希望用户两次使用相同的令牌,所以我决定保存唯一的标识符在令牌内以及HttpservletRequest中,因此我可以在获取请求时进行检查(每个请求中都会生成新的标识符(。因此,我的问题是:
1(是否有其他方法可以确保某些用户不会多次使用相同的令牌(也考虑过将该标识符保存在DB中,但是我会插入,删除,验证等的许多查询。
2(对于接收到单身顿请求的控制器是否可以,还是应该是原型?(考虑到标识符是从会话中获取的,我不想将其混合在不同的会话之间(。
在令牌上只有几个单词,这些单词仅有效
不可能实现它不在某个地方保留令牌的踪迹。此安全模式需要一些权衡,处理它。
像白色列表:
一样,给用户一个令牌并将其跟踪在服务器端- 发出令牌时,将其添加到白色列表中。
- 当请求带有令牌到服务器时,请检查白色列表,并:
- 如果令牌有效,请接受请求并从白色列表中删除令牌。
- 如果令牌无效,请通过返回正确的状态代码(例如
403
。
(拒绝请求。
此外,请考虑将到期日期分配给令牌,并拒绝使用已过期令牌到服务器的任何请求。
关于您的表现问题:请记住,过早优化是所有邪恶的根源。在遇到性能问题之前,您不应该优化,并且已证明表现问题来自您存储令牌的方式。例如,您可以开始将令牌存储在数据库中,然后考虑内存中的缓存。但是,解决您当前没有的问题时始终要小心。
与JWT
一起工作如果您去JWT,则有一些Java库要发行并验证JWT令牌,例如:
- jjwt
- java-jwt
- jose4j
jti
索赔应用于将令牌标识符存储在令牌上。在验证令牌时,请确保通过检查服务器端具有的令牌标识符的jti
索赔值。
对于令牌标识符,您可以使用UUID。在Java中,它很简单:
String uuid = UUID.randomUUID().toString();
由于httpsession#getid((是唯一的,您可以使用它来创建唯一的令牌:
// pseudo code
String token = httpSession.getId() + "-" + System.currentTimeMillis();
您也可以创建自己的计数器。
这是我预防它的两种技术
-
禁用提交按钮:我们可以在函数调用HTTP请求之前立即禁用提交按钮,并在完成后再次启用HTTP响应。该技术对于需要很长时间才能完成的过程有效(超过5秒(。由于不耐烦,用户无法再次单击n’单击。此外,我们可能会显示一个加载盒,以获得良好的体验。
-
发出请求令牌/ID:实际上,这项技术更复杂且难以实施,但是由于一个良好的框架(例如春季启动(,可以使这更容易。在进入代码实施之前,让我们先谈谈该机制;加载表单页面时,请发出新的请求ID在调用后端服务之前,将已发行的请求ID放在HTTP标头中后端服务确定requestID已注册或未注册如果已注册requestID,那么我们可以将其标记为违规请求