我正在尝试实现“记住我”/“自动登录”功能。我已经在客户端存储了一个 cookie,但我应该什么时候读取它?例如,如果我尝试在过滤器中执行此操作,我将无法访问我用来访问数据库的应用程序范围的 bean。
这样做的最佳做法是什么?
我正在尝试实现“记住我”/“自动登录”功能。我已经在客户端存储了一个 cookie,但我应该什么时候读取它?例如,如果我尝试在过滤器中执行此操作,我将无法访问我用来访问数据库的应用程序范围的 bean。
这样做的最佳做法是什么?
这在一定程度上取决于您当前登录的确切工作方式。是容器登录后跟自定义内容(例如在会话中放置一些对象)还是仅自定义?
在第一种情况下,您不能在 JSF 中完全进行自动登录,因为只要用户尝试访问受保护的资源,容器就会启动。在这种情况下,您仍然需要在过滤器 ( HttpServletRequest#login
) 中执行容器登录部分。
对于第一种和第二种情况,JSF 部分都可以通过全局PhaseListener
. 在这种情况下,您可以收听一个非常早的事件,例如before RESTORE_VIEW
。在此事件处理程序中,您可以检查会话中您放入的任何对象以标记您的登录,如果不存在,则使用HttpServletRequest
检查是否有“记住我”cookie,并在需要时继续登录。调用时PhaseListener
,JSF 完全可操作,您可以访问应用程序范围的托管 bean。
如果您只在会话中使用一个对象并且不费心进行任何容器登录,那么您可以简单地跳过第一部分。
ps
另一种选择是不要将任何数据库内容放在 JSF 托管 bean 中,因此您不需要 JSF 操作即可访问您的数据库。在 Java EE 应用程序中,EJB bean 是备选候选者(实际上更适合这项工作)。它们可以被注入到您的过滤器中,并用于在 JSF 生命周期开始之前访问数据库。除了 EJB bean,CDI bean 也是一种选择。在许多方面,这些都是 JSF 托管 bean 的更好替代方案。
只要会话处于活动状态,会话范围就会保留内容,将其与数据库中或通过 cookie 的状态持久性结合起来。
没有一个作用域会真正“记住”你的状态,你能做的最好的是将状态保存到数据库中,当用户返回时,尽可能地恢复它并将数据推送到会话作用域的 bean 中。
否则通过 cookie 扩展 sessionscope 的会话
FacesContext.getCurrentInstance().getExternalContext.addResponseCookie(..)