Làm thế nào để chuyển hướng đến trang đăng nhập khi phiên hết hạn trong ứng dụng web Java?
Đây là câu hỏi sai. Bạn nên phân biệt giữa các trường hợp "Người dùng chưa đăng nhập" và "Phiên hết hạn". Về cơ bản, bạn muốn chuyển hướng đến trang đăng nhập khi người dùng không đăng nhập. Không phải khi phiên hết hạn. Câu trả lời hiện được chấp nhận chỉ kiểm tra HttpSession#isNew()
. Nhưng điều này rõ ràng là không thành công khi người dùng đã gửi nhiều hơn một yêu cầu trong cùng một phiên khi phiên được tạo ngầm bởi JSP hoặc những gì không. Ví dụ. khi nhấn F5 trên trang đăng nhập.
Như đã nói, thay vào đó, bạn nên kiểm tra xem người dùng có đăng nhập hay không. Với thực tế là bạn đang hỏi loại câu hỏi này trong khi các khung xác thực chuẩn như j_security_check
, Shiro, Spring Security, vv đã quản lý minh bạch điều này (và do đó sẽ không cần phải hỏi loại câu hỏi này), chỉ có thể có nghĩa là bạn đang sử dụng phương thức xác thực trong nhà.
Giả sử rằng bạn đang lưu trữ cho người dùng đăng nhập trong phiên làm việc trong một số đăng nhập servlet như dưới đây:
@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);
}
}
}
Sau đó, bạn có thể kiểm tra cho rằng trong một đăng nhập filter như dưới đây:
@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);
}
}
// ...
}
Không cần phải fiddle xung quanh với giòn HttpSession#isNew()
kiểm tra.
Tại sao không sử dụng một SessionListener và chuyển hướng trên phiên bị phá hủy? –
@Mr_and_Mrs_D: vì không nhất thiết phải có yêu cầu HTTP trong quá trình hủy phiên. – BalusC