会话到期后如何重定向到登录页面? [英] How to redirect to the login page when the session expires?
问题描述
我有三个JSF 2.0 Web模块,并且会话期满后需要重定向到登录页面.
I have three JSF 2.0 web modules and I need to redirect to the login page when the session expires.
我已经尝试过使用HttpSessionListener
进行调用,它正在调用sessionDestroyed()
事件方法,但是我无法在其中转发/重定向请求.我认为是因为没有HttpServletRequest
和HttpServletResponse
对象.
I have tried it using a HttpSessionListener
, it is calling the sessionDestroyed()
event method, but I am not able to forward/redirect the request in there. I think it is becasue there are no HttpServletRequest
and HttpServletResponse
objects.
我也使用PhaseListener
进行了尝试,但它在Web浏览器中导致重定向过多"错误.
I also tried it using a PhaseListener
, but it results in a "too many redirects" error in the webbrowser.
public class SessionListener implements PhaseListener {
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
public void beforePhase(PhaseEvent event) {
if (!FacesContext.getCurrentInstance().isPostback()) {
try {
System.out.println("Session Destroyed");
FacesContext.getCurrentInstance().getExternalContext().redirect("login.jsf");
}
catch (Exception e) {
System.out.println("error" + e);
}
}
}
public void afterPhase(PhaseEvent event) {
try {
System.out.println("Session Created");
}
catch (Exception e) {
System.out.println("error" + e);
}
}
}
为什么这些尝试不起作用,我该如何最好地解决呢?
Why do those attempts not work and how can I solve it the best?
推荐答案
在会话期满的那一刻,不可能发送重定向.也就是说,客户端当时没有发送任何HTTP请求,您可以随后通过重定向进行响应.
It's not possible to send a redirect at exactly the moment when the session is expired. The client has namely not sent any HTTP request at that moment which you could then respond with a redirect.
您应该只保留现有的身份验证机制,当用户不再登录时,该机制将重定向到登录页面.您最多可以通过添加以下检查来改进它:检查用户是否已被重定向到登录页面,因为会话已过期,或者仅仅是因为他从未登录过(例如,这是一个新请求) ).
You should just keep your existing authentication mechanism which redirects to the login page when the user is not logged-in anymore. You can at best improve it by adding a check if the user is been redirected to the login page because the session has been expired, or just because he has never logged in before (i.e. it's a fresh new request).
如果 HttpServletRequest#isRequestedSessionIdValid()
返回false
(这意味着会话具有已在服务器端过期).您可以在检查登录用户的同一过滤器中执行此操作(您已经拥有一个,对吗?或者您正在使用容器管理的身份验证?).
You can check for that by if HttpServletRequest#getRequestedSessionId()
doesn't return null
(which means that the client has sent a session cookie and thus assumes that the session is still valid) and HttpServletRequest#isRequestedSessionIdValid()
returns false
(which means that the session has been expired at the server side). You can do that in the very same filter where you're checking for the logged-in user (you do already have one, right? or are you using container managed authentication?).
User user = (User) session.getAttribute("user");
if (user == null) {
String loginURL = request.getContextPath() + "/login.jsf";
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
response.sendRedirect(loginURL + "?expired=true");
} else {
response.sendRedirect(loginURL);
}
} else {
chain.doFilter(request, response);
}
然后在login.xhtml
页面中进行检查
<h:panelGroup rendered="#{param.expired}">
<p>You have been redirected to the login page, because your session was expired.</p>
</h:panelGroup>
您的相位监听器方法毫无意义.实际上,它会在每个请求上发送重定向,从而导致其在无限循环中运行.恢复视图阶段与会话到期完全无关.
Your phase listener approach makes by the way no sense. It indeed sends a redirect on every single request causing it to run in an infinite loop. The restore view phase has absolutely nothing to do with the session expiration.
这篇关于会话到期后如何重定向到登录页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!