我有一个Spring-mvc应用程序,在每个控制器中我向SessionAttributes添加一个表单,以便在保存,删除或执行另一个get请求时保留属性 . 当我尝试在另一个浏览器选项卡中打开某个链接并尝试提交第一个链接时,会出现主要问题 . 我尝试了this解决方案,但是当我进行重定向时(在控制器中我只有1个返回视图而其他方法进行重定向)它会创建一个新的对话,但找不到前一个 .
我有另一个关于这个使用spring-session的问题的问题,问题是here但我不知道这是否也会起作用 .
你看过Spring的RedirectAttributes吗?我自己没有用过,但听起来应该按照自己的意愿行事 . RedirectAttributes通常用于GET /重定向/ POST模式,并且at least one user似乎认为以这种方式传递会话属性是不好的做法,但是他们继续提到似乎没有更好的解决方案 . 无论如何,文档中显示的示例:
@RequestMapping(value = "/accounts", method = RequestMethod.POST) public String handle(Account account, BindingResult result, RedirectAttributes redirectAttrs) { if (result.hasErrors()) { return "accounts/new"; } // Save account ... redirectAttrs.addAttribute("id", account.getId()).addFlashAttribute("message", "Account created!"); return "redirect:/accounts/{id}"; }
将“message”属性添加到RedirectModel,如果您的控制器重定向,那么处理重定向的任何方法都可以访问该数据,如下所示:
@RequestMapping(value = "/accounts", method = RequestMethod.POST) public String handleRedirect(Model model) { String message = (String) model.asMap().get("message"); return new ModelAndView(); }
因此,应该可以以相同的方式添加会话属性 . 另一个参考here .
EDIT 我正在浏览Spring文档,他们也提到了这个注释@SessionAttributes . 从文档:
类型级@SessionAttributes注释声明特定处理程序使用的会话属性 . 这通常会列出模型属性的名称或模型属性的类型,这些属性应该透明地存储在会话或某些会话存储中,作为后续请求之间的表单支持bean .
这可能是你需要的吗?
而且a link to documentation on flash attributes .
这是我们提出的解决方案,与Spring无关:
在应用程序的每个html表单上,您必须包含一个隐藏字段 . 我们将此字段命名为CSRF_TOKEN . 该字段应具有随机生成的值 . 该值放在会话和隐藏字段中 . 会话属性的名称是SESSION_CSRF_TOKEN
将表单提交给服务器时,检查会话中的值(SESSION_CSRF_TOKEN)是否等于HTTP请求参数CSRF_TOKEN中发送的值 . 如果没有,您会显示某种错误消息,并停止处理 . 如果他们是平等的,继续 .
如果用户打开新选项卡或复制选项卡,则服务器将重新呈现页面,并将生成新的CSRF_TOKEN . 因此,用户只能从新打开的选项卡提交表单,而不能从原始选项卡提交 .
此解决方案提供额外的奖励:它可以防止CSRF attacks .
2 回答
你看过Spring的RedirectAttributes吗?我自己没有用过,但听起来应该按照自己的意愿行事 . RedirectAttributes通常用于GET /重定向/ POST模式,并且at least one user似乎认为以这种方式传递会话属性是不好的做法,但是他们继续提到似乎没有更好的解决方案 . 无论如何,文档中显示的示例:
将“message”属性添加到RedirectModel,如果您的控制器重定向,那么处理重定向的任何方法都可以访问该数据,如下所示:
因此,应该可以以相同的方式添加会话属性 . 另一个参考here .
EDIT 我正在浏览Spring文档,他们也提到了这个注释@SessionAttributes . 从文档:
这可能是你需要的吗?
而且a link to documentation on flash attributes .
这是我们提出的解决方案,与Spring无关:
在应用程序的每个html表单上,您必须包含一个隐藏字段 . 我们将此字段命名为CSRF_TOKEN . 该字段应具有随机生成的值 . 该值放在会话和隐藏字段中 . 会话属性的名称是SESSION_CSRF_TOKEN
将表单提交给服务器时,检查会话中的值(SESSION_CSRF_TOKEN)是否等于HTTP请求参数CSRF_TOKEN中发送的值 . 如果没有,您会显示某种错误消息,并停止处理 . 如果他们是平等的,继续 .
如果用户打开新选项卡或复制选项卡,则服务器将重新呈现页面,并将生成新的CSRF_TOKEN . 因此,用户只能从新打开的选项卡提交表单,而不能从原始选项卡提交 .
此解决方案提供额外的奖励:它可以防止CSRF attacks .