当前位置: 首页 > 知识库问答 >
问题:

用JSP和Servlet进行密码验证

贲宏硕
2023-03-14

我有一个用户登录Html表单,我在其中获取用户的电子邮件和密码并根据数据库检查它们。到目前为止,我有以下代码,但当我提交表单时,它不会转到指定的JSP页面。我可以做些什么来改进我的代码,以及当用户按下提交但仍留在同一页面上时,我如何生成错误消息?

提前谢谢你。

//SERVLET doPost方法

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userinp = request.getParameter("userinp"); //hidden type in html sign up form
        HttpSession s = request.getSession();
        User u = new User();
        if(userinp.equals("signup")) {
            u.setName(request.getParameter("name"));
            u.setLname(request.getParameter("lname"));
            u.setEmail(request.getParameter("email"));
            u.setPassword(request.getParameter("password"));
            s.setAttribute("User", u);
            //Save to DB
            u = (User)s.getAttribute("User");
            s.invalidate();
            UserM ud = new UserM(); //class which contains CRUD methods
            ud.createTable();
            ud.insert(u);
            ServletContext ctx = request.getSession().getServletContext();
            forwardTo(ctx, request, response, "/Somepage.jsp");

        } else if(userinp.equals("login")) {
            String pass1 = request.getParameter("pass");
            String email = request.getParameter("useremail");
            Connection conn = null;
            PreparedStatement stm = null;
            try {
                conn = ConnectionConfiguration.getConnection();
                stm = conn.prepareStatement("SELECT password FROM users WHERE email = ?");
                stm.setString(4, email);
                ResultSet resultSet = stm.executeQuery();
                while(resultSet.next()) {
                    String pass2 = resultSet.getString("password");
                    if(pass1.equals(pass2)) {
                        ServletContext ctx = request.getSession().getServletContext();
                        forwardTo(ctx, request, response, "/Somepage.jsp");
                        } else {
                            //code to generate "Wrong Password" message
                        }
                    }
                } catch(Exception e) {
                    e.printStackTrace();
                } finally {
                    if(stm != null) {
                        try {
                            stm.close();
                        } catch (SQLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    if(conn != null) {
                        try {
                            conn.close();
                        } catch (SQLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }

        }
    }

//前向法

public static void forwardTo(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String dest)  throws ServletException
{
    RequestDispatcher rd = ctx.getRequestDispatcher(dest);
    try
    {
        rd.forward(req, resp);
    }
    catch(Throwable t)
    {
        t.printStackTrace();
        throw new ServletException(t);
    }
}

//HTML表单

<html>
<head>
<meta charset="ISO-8859-1">
</head>
<body>
<form action = "UserServ" method="POST">
<h3>Enter the details below to Sign In</h3><br>
Email: <input type="text" name="useremail" required><br>
Password: <input type="password" name="pass" required><br>
<input type="submit" value="Sign In">
</form>
</body>
</html>

共有1个答案

阎单鹗
2023-03-14

你有一个错误在你的数据库准备声明:

  stm.setString(4, email);

4应该是什么?setString的第一个参数对应于“?”在你准备好的声明中。

   stm = conn.prepareStatement("SELECT password FROM users WHERE email = ?");

你只有一个问号,所以应该是:

   stm.setString(1, email);

我能做些什么来改进我的代码

将数据库逻辑与servlet分离。使用MVC模式,它会让你的生活更轻松。

我怎样才能产生一个错误呢

在JSP中使用JSTL/EL可以轻松实现这一点。在servlet中设置一个属性,并将其转发到jsp页面。JSTL将检查该属性是否存在,并显示相应的消息。

如果详细信息错误,您也可以将用户转发到特定页面,就像我在下面的示例中所示的那样。

更高级的方法是实现AJAX,这基本上是使用javascript对servlet进行异步调用,这样就不必刷新页面。你可以用这个来检查细节是否正确。

当用户按submit但仍停留在同一页面时的消息?

你是说如果他们没有输入任何细节?可以使用javascript/jquery来实现这一点。当文本字段为空时,可能会禁用提交btn/表单。

下面是您的servlet代码,我浓缩了您的数据库逻辑。这种方式更容易管理:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String userinp = request.getParameter("userinp"); //hidden type in html sign up form
    HttpSession s = request.getSession();
    User u = new User();
    ServletContext ctx = s.getServletContext();
    //check for null first, because if userinp is empty, then you will get a NPE
    if(userinp != null && userinp.equals("signup")) {
        u.setName(request.getParameter("name"));
        u.setLname(request.getParameter("lname"));
        u.setEmail(request.getParameter("email"));
        u.setPassword(request.getParameter("password"));
        s.setAttribute("User", u);
        //Save to DB
        u = (User)s.getAttribute("User");
        s.invalidate();
        UserM ud = new UserM(); //class which contains CRUD methods
        ud.createTable(); //why are you creating a table for each user? (you need to create a table called 'users' and just insert the new user there.
        ud.insert(u);

        forwardTo(ctx, request, response, "/Somepage.jsp");

    } else if( userinp != null && userinp.equals("login")) { //you should separate the register and login logic (easier to maintain in two different servlets
        String pass1 = request.getParameter("pass");
        String email = request.getParameter("useremail");


        //so instead of getting the password from the database, you can check to see if the details exist instead and return a boolean. 
        if(validate(email,pass1)){

        forwardTo(ctx, request, response, "/Welcome.jsp"); //user is logged in

        }else{

        forwardTo(ctx, request, response, "/Error.jsp"); //user is not logged in, details do not match

        }

    }

}

验证方法:

//this should be in a different class. So it's easier to maintain and can be used elsewhere. It's bad practice to have database logic in your servlet. Because what if you want to use this in a different servlet or another part of your application? (you don't want to copy and pasta it everywhere do you?)

public static boolean validate(String email, String password){          
     boolean status = false;  
    PreparedStatement pst = null;  
    ResultSet rs = null;  
     //if you put your getConnection method as a try condition, it will automagically close the connection for you. 
    try(Connection conn= ConnectionConfiguration.getConnection()){

        pst = conn.prepareStatement("select * from users where email=? and password=?;");  
        pst.setString(1, email);   //1 here corresponds to the first '?' in preparedStatement
        pst.setString(2, password);  //2 corresponds to the second '?'
        rs = pst.executeQuery();  

        status = rs.next();  //if there are any results, then status is true. 
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return status;  
}

让我知道,如果你有任何问题或其他问题,乐意帮助。

 类似资料:
  • 本文向大家介绍Jsp servlet验证码工具类分享,包括了Jsp servlet验证码工具类分享的使用技巧和注意事项,需要的朋友参考一下 昨晚在csdn看到一位前辈写一个ajax+servlet+jsp验证,顿时心血来潮,在阅读前辈的代码下我亲手体验一下,做了一个验证码生成工具类,以供大家做个参考。 1、添加VeriyCodeUtils类生成验证码图像 2、servlet使用验证码 3、JSP页

  • 本文向大家介绍JSP使用Servlet过滤器进行身份验证的方法,包括了JSP使用Servlet过滤器进行身份验证的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JSP使用Servlet过滤器进行身份验证的方法。分享给大家供大家参考,具体如下: 1、Servlet过滤器的作用描述 (1)在HttpServletRequest到达Servlet 之前,拦截客户的HttpServletRe

  • 我使用包括Spring Security和Vaadin在内的https://start.spring.io设置了一个Spring Boot项目。然后我将Vaadin版本设置为22.0.4,并按照本教程使用Vaadin Flow和Spring Security设置登录页面:https://vaadin.com/docs/v22/flow/tutorial/login-and-authenticati

  • 客户已创建密钥存储库并存储凭据。为了验证密钥存储库,我已经在节点中创建了应用程序,并使用客户端id和客户端机密,我能够读取机密。但是现在客户不想使用客户id和客户机密,而是使用AZURE的用户名和密码来访问程序中的keyvault。它是一个没有MFA的keyvault访问的专用用户。 我不确定我们是否可以从节点JS使用用户名和密码访问keyvault。敬请建议。 谢谢

  • 问题内容: 我正在用Java进行基于密码的文件加密;我正在使用AES作为底层加密算法,并使用以下代码(我是从该网站的另一位慷慨的海报获得者)从盐和密码的组合中得出密钥的。 我吃了盐,用户在两端输入密码,加密和解密工作正常:-)我的问题是,我希望能够在进入(可能很长)之前验证用户输入的密码是否正确解密过程。我知道PBKD规范包含一个可选的2字节验证值,但是我不确定如何使用上述方法生成该值。Java是

  • 我试图使用regex或JavaScript实现密码验证。不幸的是,我完全是Regex的新手:/ null 谢谢