user10479159
user10479159

Reputation:

Password validation with JSP and Servlet

I have a user Sign in Html form where I get the user's email and password and check them against a database. So far I have the following code but when I submit the form it does not go to the specified JSP page. What can I do to improve my code and how can I just generate an error message when the user presses submit but still stay on the same page?

Thank you in advance.

//SERVLET doPost Method

    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();
                        }
                    }
                }

        }
    }

//ForwardTo Method

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 FORM

<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>

Upvotes: 0

Views: 3626

Answers (1)

Jonathan Laliberte
Jonathan Laliberte

Reputation: 2725

You have an error in your database preparedStatement:

  stm.setString(4, email);

What is 4 supposed to be here? The first parameter of setString corresponds to the '?' in your prepared statement.

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

You only have 1 question mark, so it should be:

   stm.setString(1, email);

What can I do to improve my code

Seperate the database logic from your servlet. Use the MVC pattern, it will make your life easier.

and how can I just generate an error

You can easily achieve this with JSTL/EL in your JSP. Set an attribute in your servlet and forward that to the jsp page. JSTL will check if the attribute exists and show the appropriate message.

You could also just forward the user to a specific page if the details are wrong, like i have shown in the example below.

A more advanced way would be to implement AJAX, this is basically using javascript to make asynchronous calls to your servlet so that you don't have to refresh the page. You could use this to check see if the details are correct.

message when the user presses submit but still stay on the same page?

You mean if they haven't typed in any details? You could use javascript/jquery to do this. Maybe disable the submit btn/form from submitting when the text fields are empty.

Below is your servlet code, i condensed your database logic. Much easier to manage this way:

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

        }

    }

}

validate method:

//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;  
}

Let me know if you have problems anywhere or other questions, happy to help.

Upvotes: 1

Related Questions