当会话在 Java Web 应用程序中过期时如何重定向到登录页面?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1026846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to redirect to Login page when Session is expired in Java web application?
提问by Veera
I'm running a web application in JBoss AS 5. I also have a servlet filter which intercepts all the requests to the server. Now, I want to redirect the users to the login page, if the session has expired. I need to do this 'isSessionExpired()' check in the filter and need to redirect the user accordingly. How do I do it? I'm setting my session time limit in web.xml, as below:
我在 JBoss AS 5 中运行一个 web 应用程序。我还有一个 servlet 过滤器,它拦截对服务器的所有请求。现在,如果会话已过期,我想将用户重定向到登录页面。我需要在过滤器中执行此“isSessionExpired()”检查,并需要相应地重定向用户。我该怎么做?我在 web.xml 中设置我的会话时间限制,如下所示:
<session-config>
<session-timeout>15</session-timeout>
</session-config>
采纳答案by Alex
You could use a Filterand do the following test:
您可以使用过滤器并执行以下测试:
HttpSession session = request.getSession(false);// don't create if it doesn't exist
if(session != null && !session.isNew()) {
chain.doFilter(request, response);
} else {
response.sendRedirect("/login.jsp");
}
The above code is untested.
以上代码未经测试。
This isn't the most extensive solution however. You should also test that some domain-specific object or flag is available in the session before assuming that because a session isn't new the user must've logged in. Be paranoid!
然而,这不是最广泛的解决方案。你应该还测试了一些特定领域的对象或标志是在会话中可用假设,因为会话不是新用户意有所指登录之前,偏执!
回答by zkarthik
Check for session is new.
检查会话是新的。
HttpSession session = request.getSession(false);
if (!session.isNew()) {
// Session is valid
}
else {
//Session has expired - redirect to login.jsp
}
回答by sampath
When the use logs in, put its username in the session:
当用户登录时,将其用户名放入会话中:
`session.setAttribute("USER", username);`
At the beginning of each page you can do this:
在每个页面的开头,您可以执行以下操作:
<%
String username = (String)session.getAttribute("USER");
if(username==null)
// if session is expired, forward it to login page
%>
<jsp:forward page="Login.jsp" />
<% { } %>
回答by mukut
Inside the filter inject this JavaScript which will bring the login page like this. If you don't do this then in your AJAX call you will get login page and the contents of login page will be appended.
在过滤器内部注入这个 JavaScript,它将带来这样的登录页面。如果您不这样做,那么在您的 AJAX 调用中,您将获得登录页面并附加登录页面的内容。
Inside your filter or redirect insert this script in response:
在您的过滤器或重定向中插入此脚本作为响应:
String scr = "<script>window.location=\""+request.getContextPath()+"/login.do\"</script>";
response.getWriter().write(scr);
回答by kafrlust
you can also do it with a filter like this:
你也可以用这样的过滤器来做到这一点:
public class RedirectFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest)request;
//check if "role" attribute is null
if(req.getSession().getAttribute("role")==null) {
//forward request to login.jsp
req.getRequestDispatcher("/login.jsp").forward(request, response);
} else {
chain.doFilter(request, response);
}
}
}
回答by Anirudh Jadhav
Until the session timeout we get a normal request, after which we get an Ajax request. We can identify it the following way:
在会话超时之前,我们收到一个正常请求,之后我们收到一个 Ajax 请求。我们可以通过以下方式识别:
String ajaxRequestHeader = request.getHeader("X-Requested-With");
if ("XMLHttpRequest".equals(ajaxRequestHeader)) {
response.sendRedirect("/login.jsp");
}
回答by LoGos
i found this posible solution:
我找到了这个可行的解决方案:
public void logout() {
ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
String ctxPath = ((ServletContext) ctx.getContext()).getContextPath();
try {
//Use the context of JSF for invalidate the session,
//without servlet
((HttpSession) ctx.getSession(false)).invalidate();
//redirect with JSF context.
ctx.redirect(ctxPath + "absolute/path/index.jsp");
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
回答by BalusC
How to redirect to Login page when Session is expired in Java web application?
当会话在 Java Web 应用程序中过期时如何重定向到登录页面?
This is a wrong question. You should differentiate between the cases "User is not logged in" and "Session is expired". You basically want to redirect to login page when user is not logged in. Not when session is expired. The currently accepted answer only checks HttpSession#isNew()
. But this obviously fails when the user has sent more than one request in the same session when the session is implicitly created by the JSP or what not. E.g. when just pressing F5 on the login page.
这是一个错误的问题。您应该区分“用户未登录”和“会话已过期”的情况。您基本上希望在用户未登录时重定向到登录页面。而不是在会话过期时。当前接受的答案仅检查HttpSession#isNew()
. 但是当用户在同一个会话中发送了多个请求时,如果会话是由 JSP 隐式创建的,或者不是什么,这显然会失败。例如,在登录页面上按 F5 时。
As said, you should instead be checking if the user is logged in or not. Given the fact that you're asking this kind of question while standard authentication frameworks like j_security_check
, Shiro, Spring Security, etc already transparently manage this (and thus there would be no need to ask this kind of question on them), that can only mean that you're using a homegrown authentication approach.
如上所述,您应该检查用户是否已登录。鉴于您提出此类问题,而标准身份验证框架(如j_security_check
、Shiro、Spring Security 等已经透明地管理此问题(因此无需向他们提出此类问题),这只能意味着您正在使用本土的身份验证方法。
Assuming that you're storing the logged-in user in the session in some login servletlike below:
假设您将登录用户存储在会话中的某个登录servlet 中,如下所示:
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@EJB
private UserService userService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath() + "/home");
} else {
request.setAttribute("error", "Unknown login, try again");
doGet(request, response);
}
}
}
Then you can check for that in a login filterlike below:
然后,您可以在如下所示的登录过滤器中进行检查:
@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/login";
boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean loginRequest = request.getRequestURI().equals(loginURI);
if (loggedIn || loginRequest) {
chain.doFilter(request, response);
} else {
response.sendRedirect(loginURI);
}
}
// ...
}
No need to fiddle around with brittle HttpSession#isNew()
checks.
无需摆弄脆弱的HttpSession#isNew()
支票。
回答by Sunil Pidugu
You need to implement the HttpSessionListener
interface, server will notify session time outs.
您需要实现该HttpSessionListener
接口,服务器会通知会话超时。
like this;
像这样;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class ApplicationSessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent event) {
System.out.println("Session Created");
}
public void sessionDestroyed(HttpSessionEvent event) {
//write your logic
System.out.println("Session Destroyed");
}
}
Check this example for better understanding
检查此示例以更好地理解