使用 Servlet 和 JSP 检查用户是否登录 £神魔★判官ぃ 2023-09-27 10:58 61阅读 0赞 ### **1. 概述** ### 在本教程中,我们将学习如何检查用户的登录并确保用户已使用有效凭据填写登录表单并开始会话。**但是,我们将在不使用[Spring Security][]并且仅使用 JSP 和[servlet][]的情况下执行此操作。**因此,我们需要一个可以支持它的 servlet 容器,比如 Tomcat 9。 到最后,我们将很好地理解事情是如何在幕后工作的。 ### **2. 持久化策略** ### 首先,我们需要用户。为了简单起见,我们将使用预加载的地图。*让我们和我们的User*一起定义它: public class User { static HashMap<String, User> DB = new HashMap<>(); static { DB.put("user", new User("user", "pass")); // ... } private String name; private String password; // getters and setters } ### **3.过滤请求** ### 我们将首先创建一个[过滤器][Link 1]来检查无会话请求,阻止直接访问我们的 servlet: @WebFilter("/*") public class UserCheckFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { // ... request.setAttribute("origin", request.getRequestURI()); if (!request.getRequestURI().contains("login") && request.getSession(false) == null) { forward(request, response, "/login.jsp"); return; } chain.doFilter(request, response); } } **在这里,通过在*@WebFilter上将“* */\** ”定义为我们的 URL 模式,所有请求都将首先通过我们的过滤器。**然后,如果还没有会话,我们将请求重定向到我们的登录页面,存储*源*以供以后使用。最后,我们提前返回,防止我们的 servlet 在没有适当会话的情况下进行处理。 ### **4. 使用 JSP 创建登录表单** ### 要构建我们的登录表单,我们需要从[JSTL][]导入核心 Taglib 。另外,让我们在*页面*指令中将*会话* 属性设置为“ *false* ” 。结果,不会自动创建新会话,我们可以完全控制: <%@ page session="false"%> <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> <form action="login" method="POST"> ... </form> 然后,在我们的*表单*中,我们将有一个隐藏的输入来保存*原点*: <input type="hidden" name="origin" value="${origin}"> 接下来,我们将包含一个条件元素来输出错误: <c:if test="${not empty error}"> * error: ${error} </c:if> 最后,让我们添加一些*输入*标签,以便用户可以输入和提交凭据: <input type="text" name="name"> <input type="password" name="password"> <input type="submit"> ### **5. 设置我们的登录 Servlet** ### *在我们的 servlet 中,如果它是GET*,我们会将请求转发到我们的登录表单。**最重要的是,我们验证登录是否是*POST***: @WebServlet("/login") public class UserCheckLoginServlet extends HttpServlet { // ... } 因此,在我们的*doGet()*方法中,我们将重定向到我们的登录 JSP,并向前传递*原点*: protected void doGet(HttpServletRequest request, HttpServletResponse response) { String referer = (String) request.getAttribute("origin"); request.setAttribute("origin", referer); forward(request, response, "/login.jsp"); } 在我们的*doPost()*中,我们验证凭据并创建一个会话,将*User*对象转发并重定向到*origin*: protected void doPost(HttpServletRequest request, HttpServletResponse response) { String key = request.getParameter("name"); String pass = request.getParameter("password"); User user = User.DB.get(key); if (!user.getPassword().equals(pass)) { request.setAttribute("error", "invalid login"); forward(request, response, "/login.jsp"); return; } HttpSession session = request.getSession(); session.setAttribute("user", user); response.sendRedirect(request.getParameter("origin")); } **如果凭据无效,我们会在*错误*变量**中设置一条消息。否则,我们用我们的*用户*对象更新会话。 ### **6.检查登录信息** ### 最后,让我们创建我们的主页。它只显示会话信息并有一个注销链接: <body> current session info: ${user.name} <a href="logout">logout</a> </body> 我们的 home servlet 所做的只是将*用户*转发到主页: @WebServlet("/home") public class UserCheckServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) { User user = (User) session.getAttribute("user"); request.setAttribute("user", user); forward(request, response, "/home.jsp"); } } 这就是它的外观: ![804cbae105d54a21966640d4bc362436.webp][] ### **7. 登出** ### **要注销,我们只需使当前会话无效并重定向 home**。之后,我们的*UserCheckFilter*将检测到无会话请求并将我们重定向回登录页面,重新启动该过程: @WebServlet("/logout") public class UserCheckLogoutServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) { request.getSession().invalidate(); response.sendRedirect("./"); } } ### **8. 结论** ### 在本文中,我们创建了一个完整的登录周期。我们看到了现在如何使用单个过滤器完全控制对 servlet 的访问。简而言之,通过这种方法,我们始终可以确保我们需要一个有效的会话。同样,我们可以扩展该机制以实现更精细的访问控制。 与往常一样,源代码可[在 GitHub 上][GitHub]获得。 [Spring Security]: https://www.baeldung.com/spring-security-login [servlet]: https://www.baeldung.com/register-servlet [Link 1]: https://www.baeldung.com/intercepting-filter-pattern-in-java [JSTL]: https://www.baeldung.com/jstl [804cbae105d54a21966640d4bc362436.webp]: https://img-blog.csdnimg.cn/804cbae105d54a21966640d4bc362436.webp [GitHub]: https://github.com/eugenp/tutorials/tree/master/web-modules/javax-servlets-2
还没有评论,来说两句吧...