Validate email address and password - java

How do I validate a certain email and password while an user logs in?
protected void doPost(HttpServletRequest request, HttpServletResponse res) throws IOException, ServletException {
String email=request.getParameter("email");
String pass=request.getParameter("pass");
OutputStream out = res.getOutputStream();
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:8080/college", "root", "root");
Statement st=con.createStatement();
String strSQL = "SELECT email,password FROM student";
How do I continue after the SELECT statement? I would prefer using the if...else statement to do the validation.

First close all connection resources properly - use a Java 7 try-with-resources.
Here is an simple example:
final String email = request.getParameter("email");
final String pass = request.getParameter("pass");
try (final Connection con = DriverManager.getConnection("jdbc:mysql://localhost:8080/student", "root", "root");
final PreparedStatement statement = con.prepareStatement("SELECT COUNT(*) AS count FROM student WHERE email=? AND password=?");) {
statement.setString(1, email);
statement.setString(2, pass);
try (final ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
final int rows = resultSet.getInt("count");
if (rows > 1) {
throw new IllegalStateException("More than one row returned!");
}
boolean validUser = rows == 1;
}
}
}
But really you should hash passwords in the database. Use something like jBcrypt. Your code would then look like:
final String email = request.getParameter("email");
final String pass = request.getParameter("pass");
try (final Connection con = DriverManager.getConnection("jdbc:mysql://localhost:8080/student", "root", "root");
final PreparedStatement statement = con.prepareStatement("SELECT pass FROM student WHERE email=?");) {
statement.setString(1, email);
statement.setString(2, pass);
try (final ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
final String hash = resultSet.getString("pass");
final boolean valid = BCrypt.checkpw(pass, hash);
}
}
}
Obviously you need to add error checking if there are no rows returned from the query. You also need to check that only one row is returned. But I leave that as an exercise.

you can use if, if you like. Use the input as your where statement and then check to see if there is a match, error or null, then execute whatever you want it to do.

You can use email and password in the SQL statement itself. like:
SELECT email, password from student where email = ? and password = ?
prepare above statement and bind the parameters.
This way validation will be done on the DB and you just need to check the result count (which has to be 1). You should have index on email column to have better SQL performance.

Do you relay need to fetch all students?
PreparedStatement st = con.prepareStatement("SELECT count(*) FROM student WHERE email=? AND password=?");
st.setString(1, email);
st.setString(2, pass);
ResultSet rs = st.executeQuery();
rs.next();
int count = rs.getInt(1);
if (count == 1) {
// password and email are correct
}

For this answer, I'll assume that by "validate email and password", what you mean is you want to authenticate the user based on their email address and a password. And not that you want to check whether the email address is a real email address.
So, the first thing you need to do is encrypt the passwords in your database, using a hash algorithm and a random salt. You record the salt alongside the hashed password.
Next thing is, when the user logs in, you look up the salt for that user, and you perform the same hash with the salt. Then you compare the result of that with the previously saved password hash, and if they're the same, then the passwords were the same.
It's important that the salt be random and different for every user.
Plenty of reading to be found on the above terms on the Internets.
Once you've done that, you should also apply the very sensible suggestions in other answers to only select the user you want, and handle your resources correctly.
WARNING I am not an expert on security, and neither are you. If you're implementing a log-in system for an exercise, fine. If it's for the real world, use something that's been written by someone who knows what they're doing.

Related

how to prevent duplication. Java,SQL

I try duplicate the entries in the username column but the result is always in the else statement which is the data is successfully inserted into the table which should not be duplicated based on the if statement. By the way String value1=username1.getText();.
here's the code:
String sq = "SELECT username FROM login where username = '"+value1+"'";
if (sq.equals(value1)){
JOptionPane.showMessageDialog(null,"username is already existed! please
create new username.");
}
else{
int k=st.executeUpdate("insert into
login(username,password,firstname,lastname,address,contactno)
values('"+value1+"','"+value2+"','"+value3+"','"+value4+"',
'"+value5+"','"+value6+"')");
JOptionPane.showMessageDialog(null,"Data is successfully saved");
}
You just create the SQL string and never run it (instead, you compare it to the username, which will always be false).
You should actually execute it and check the result.
E.g. (error handling and resource cleanup omitted for brevity's sake):
Connection conn = // Connect to the database...
PreparedStatement ps =
conn.prepareStatement("SELECT username FROM login where username = ?";
ps.setString(1, value1);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
JOptionPane.showMessageDialog
(null,"username is already existed! please create new username.");
}
sq will never be equal to value1 if you just assign it to a complete SELECT statement:
String sq = "SELECT username FROM login where username = '"+value1+"'";
What you are missing is the DB request for your sq String.
sq contains the query (sql code)
String sq = "SELECT username FROM login where username = '"+value1+"'";
value1 contains the username value (for example "user1"). So
sq.equals(value1)
will be always false
"SELECT username FROM login where username = '"+value1+"'" != value1
String Basics:
String sq = "Something in double quotes"
Assigns Something to sq.
And
String value1=username1.getText();
May get some other string, lets say for example "root"
sq.equals(value1)
Now String class equals() method check content of both Strings(sq and value1).
And if not equal returns false, which happens in your case.
Now how to achieve your goal? people already answered that check it.
I recommend to study yourself

Compare entered Password with BCrypt hashed Password in Database

I am trying to make login where the entered Password and Username is compared with my Database and if they both match you can login.
I just started working with MySQL and BCrypt.
Here is my code so far:
#FXML
void anmeldenButton(ActionEvent event) throws NamingException, ClassNotFoundException {
String myUrl = "jdbc:mysql://localhost:3306/pwmanager?verifyServerCertificate=false&useSSL=true";
Connection conn = null;
username = tfuser1.getText().toString();
try {
conn = DriverManager.getConnection(myUrl, "", "");
query = "SELECT benutzername, passwort FROM nutzer WHERE (benutzername = ? and passwort = ?)";
PreparedStatement ps = conn.prepareStatement(query);
ps.setString(1, username);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
while (rs.isBeforeFirst()) {
checkUser = rs.getString(1);
checkPass = rs.getString(3);
if (BCrypt.checkpw(pf1.getText(), checkPass) && (checkUser.equals(username))) {
System.out.println("yay");
} else {
System.out.println("ney");
}
}
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Thanks for your help!
Your code doesn't make much sense.
The entered password can't possibly be equal to the stored password, since the stored password is hashed, and the entered password is not. So you can't use
and passwort = ?
Second, your query selects only two values, but you then use
checkPass = rs.getString(3)
You need to get the stored hashed password from the database thanks to the user name only, and then use Bcrypt to verify that the entered password and the stored hashed password match.
Also,
while (rs.isBeforeFirst())
doesn't make much sense either, and the query is supposed to return 0 or one row. So just use
if (rs.next())

JDBC - authorization users via database

I've made a program which is getting data from database and then authorizing, but the problem is only the last record is correct - logging in is succesful.
public class Test {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/uzytkownicy";
static final String USER = "root";
static final String PASS = "";
public static void main(String[] args) throws SQLException, ClassNotFoundException {
System.out.print("login: ");
Scanner zm1= new Scanner(System.in);
String name = zm1.next();
System.out.print("pass: ");
Scanner zm2 = new Scanner(System.in);
String password = zm2.next();
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting...");
Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
Statement stmt = conn.createStatement();
String sql = "SELECT logins, passwords FROM users";
ResultSet rs = stmt.executeQuery(sql);
String databasePassword = null;
String databaseUsername = null;
while (rs.next()) {
databaseUsername = rs.getString("logins");
databasePassword = rs.getString("passwords");
}
if (name.equals(databaseUsername) && password.equals(databasePassword)) {
System.out.println("Logged in!");
}
else {
System.out.println("Bad Pass/Login");
}
rs.close();
stmt.close();
conn.close();
}
catch(SQLException se){
se.printStackTrace();
}
}
}
If I'm understanding what you're trying to do (which I may not be), your problem is that the comparison of username and password is outside the while loop, so your:
while (rs.next())
just loops through the entire result set, so when the while loop ends, databaseUsername and databasePassword will be set to the values from the last row read.
Instead, move the comparison inside the loop and set a flag (defaulting to false) and break out of the loop if the correct username and password is found, then use that flag to determine what to print.
Also, you might want to read up on parameterized queries. You can actually have the database do all the work for you by using a PreparedStatement and making your query:
SELECT 1 from users where logins = ? and passwords = ?;
If the result set contains anything, then the user entered a valid username and password, otherwise they didn't. The question marks in the query would be set to name and password using the set* methods of PreparedStatement.
Another note--storing plaintext passwords is a horrible idea. If the table storing the passwords is exposed (through various attacks or just a disgruntled employee stealing it), then everyone has all your users' passwords. Eek! You might argue that you'll take steps to prevent that, but from a security perspective, it's best to assume someday the table will be compromised, and do everything you can to ensure that it's not too harmful.

Checking Credentials against Db using JDBC

i've been trying to make this piece of code work work for a while now but seems like it wont. My User inputs Username and Password and then the program compares it to the DB. However it displays Invalid Credentials even though when i output the password it displays the exact same i've input.Just a few points, i know some of you are going to point on things like Using a seperate class for Connection, Check against username for password instead of using Select *, use hashings and all. But right now at the moment i just need to get this code work. Only after that i will be able to work on other aspects to ENHANCE its efficiency. Thank you all in advance.:)
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
// TODO add your handling code here:
Username1 = "jTextField1.getText()";
Password1 = "jPassword1Field2.geText()";
try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://localhost:3306/";
String dbName = "VideoSystem" ;
String userName = "root";
String passWord = "**mypassword**";
Connection conn = DriverManager.getConnection(url+dbName, userName, passWord);
Statement st = conn.createStatement();
String sql = ("SELECT * FROM Identification");
ResultSet rs = st.executeQuery(sql);
while(rs.next())
{
password = rs.getString("Password");
if( Password1.equals(password))
{
MenuSelection obj1 = new MenuSelection();
obj1.setVisible(true);
}
else
{
JOptionPane.showMessageDialog(null, "Invalid Credentials", "System Message", JOptionPane.INFORMATION_MESSAGE);
}
}
conn.close();
}
catch (Exception e)
{
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
}
Those two lines:
Username1 = "jTextField1.getText()";
Password1 = "jPassword1Field2.geText()";
They are string literals, so unless your password is literally jPassword1Field2.geText(), there's not gonna be a match. I think you meant:
Username1 = jTextField1.getText();
Password1 = jPassword1Field2.getText();
Note however, that JPasswordField.getText() is deprecated since Java 2. You should use getPassword() instead:
Password1 = new String(jPassword1Field2.getPassword());
The documentation justifies the deprecation of getText() with "security reasons" that I can't claim to understand, but you still shouldn't use deprecated parts of the API.
And I know you some of the below already and none of that is part of your question, but I really suggest that you
Check against the username. It should be obvious why.
Hash passwords. Always.
Only fetch what you need, mostly for performance reasons. Usually the best way is to use a WHERE clause in SQL (that brings the need to sanitize your input, but you should do that anyway) and building a list of columns instead of fetching *.
Use backticks for database/table/column names in SQL to avoid things like accidentally using a keyword as table/column name or so.
Applying the above, I suggest the following query (assuming the name field is called Username):
PreparedStatement st = conn.prepareStatement("SELECT `Password` FROM `Identification` WHERE `Username` = ?");
st.setString(1, Username1);
ResultSet rs = st.executeQuery();

Duplicate entry whilst using Insert in preparedStatment and retrieving previous data whilst matching results

public int addUsers(int USER_ID,String FIRST_NAME,String LAST_NAME,String PASSWORD,String USERNAME,String USER_PERMISSION) throws SQLException {
Connection conn = null;
conn = getConnectivity(conn) ;
getConnectivity(conn);
String sqlSelect = "SELECT * from USER_DETAILS";
PreparedStatement pres = conn.prepareStatement(sqlSelect);
ResultSet rs1 = pres.executeQuery();
if(rs1.next()){
String Username = rs1.getString(5);
System.out.println("username found "+Username);
System.out.println("username input " + USERNAME);
System.out.println("password input " + PASSWORD);
if (Username.equals(USERNAME)){
System.out.println("Username already exists");
conn.close();
}
else{
System.out.println("FOUND ELSE");
String sql = "INSERT INTO USER_DETAILS VALUES (?,?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, USER_ID);
ps.setString(2, FIRST_NAME);
ps.setString(3,LAST_NAME);
ps.setString(4,PASSWORD);
ps.setString(5,USERNAME);
ps.setString(6,USER_PERMISSION);
int result = ps.executeUpdate();
System.out.println(result);
}
}
conn.close();
return USER_ID;
}
and for login I am using
public boolean login(String USERNAME, String PASSWORD) throws SQLException
{
boolean result = false;
Connection conn = null;
conn = getConnectivity(conn) ;
String sqlSelect = "SELECT * from USER_DETAILS";
PreparedStatement pres = conn.prepareStatement(sqlSelect);
ResultSet rs1 = pres.executeQuery();
if(rs1.next()){
String Username = rs1.getString(5);
String Password = rs1.getString(4);
String UserPermission = rs1.getString(6);
System.out.println("username found "+Username);
System.out.println("username input " + USERNAME);
System.out.println("password input " + PASSWORD);
if (Username.equalsIgnoreCase(USERNAME) && Password.equalsIgnoreCase(PASSWORD) && UserPermission.equalsIgnoreCase("blocked")){
System.out.println("User Logged in");
conn.close();
}
System.out.println("gets out of the code");
}
conn.close();
return result;
}
first of all it is allowing to enter more than one entry, so duplicates occurring regardless of my if statement, and when i add fresh new data and try to see I can log in, it still compares with previously added data and does not work. Can someone see what am i doing wrong here. please thanks
below is the system print out i get ,
Connection Valid
username found kamran (don't know why he is still picking up this column)
username input macbook (these i have already in my database)
password input hello (these i have already in my database)
gets out of the code
Connection Valid
Connection Valid
username found kamran (don't know why he is still picking up this column)
username input macho (these i have already in my database)
password input hello (these i have already in my database)
FOUND ELSE (dont know why it adds data when they already exist in database)
1
Your code doesn't make sense: you are querying for all users and only checking the first returned user if it matches. Of course that is going to fail if the first returned user doesn't match: in addUsers you will try to add the user if the first user returned doesn't match, in login a user can only login if it is the first user.
You need to use a WHERE clause to only request the user you want to check:
// Note: this assumes a case insensitive collation
String sqlSelect = "SELECT * from USER_DETAILS WHERE username = ?";
try (PreparedStatement pres = conn.prepareStatement(sqlSelect)) {
pres.setString(1, USERNAME);
try (ResultSet rs1 = pres.executeQuery()) {
if (!rs1.next) {
// user doesn't exist yet, create...
}
}
}
You need to do something similar for login (but then with if (rs1.next()) instead).
There are more problems with your current code: you are storing plaintext passwords: you should really hash them with a strong password hash like PBKDF2. Also please follow the java naming conventions. Variables and parameters are camelcase so not USERNAME but username (or userName), not UserPermission, but userPermission. This improves the readability for people who are used to the java naming conventions.

Categories

Resources