I use this method in my database class which checks the password and yahooId ,if they were correct it allows the user to go to the next frame .I have added a lot of yahooId and password in my sql but this method just checks the last row and allows the last person to go to the next frame.would you please help me? thanks.
public static boolean Test(String userName, String password) {
boolean bool = false;
Statement stmt = null;
try {
stmt = conn.createStatement();
ResultSet rst = null;
rst = stmt.executeQuery("SELECT yahooId , password FROM clienttable");
while (rst.next()) {
if (rst.getString(1).equals(userName) && rst.getString(2).equals(password)) {
bool = true;
break;
} else {
bool = false;
}
}
} catch (SQLException ex) {
Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(bool);
return bool;
}
Don't select all the rows when you're interested in just one of them. Use a WHERE clause, which is its raison d'etre:
SELECT yahooId , password FROM clienttable WHERE yahooId=? AND password=?
If the result set is empty, authentication fails. If there's a single result, authentication succeeds. If there's more than one result, your dataset is munged (a UNIQUE index on yahooID is the proper way of preventing this).
The question marks, by the way, come from using prepared statements, if you haven't seen them before.
The problem is you're reading in the whole clienttable just to find a match for a specific user.
Instead, be VERY specific with your query to only look for a specific record that matches:
SELECT yahooId, password FROM clienttable WHERE yahooid = "UserName"
If that query returns a record, then you know the user exists. You can then check the password matches what is supplied to your method (I'm hoping you're not storing the password in plain text...).
This approach, enables you if you wanted to in the future, keep track of unsuccessful logon attempts to a user's account. And is much much more performant/scalable than loop round every record to find one match.
Related
There is a registration form on my web application. What I want is, when a user submits the form, validation should be done to check if the email id which the user entered already exists or not in the database.
And accordingly, if it exists then a message like in a snackbar should appear saying, the email id already exists. If it's a new email, then it will redirect to the success page.
Following is my checkData method where I am just checking if when I enter the email id on the form, it exists or not, but the ouput is always "value not found".
public void checkData() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname?autoReconnect=true&useSSL=FALSE", "root", "pwd");
st = con.createStatement();
String query1 = "select email from users where email='" +email99+ "'";
ResultSet rs = st.executeQuery(query1);
if(rs.next()) {
System.out.println("Success");
}
else {
System.out.println("Value not found");
}
rs.close();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
}
}
Note:- My main concern is email validation.
Thank you
For Email validation
you have to set email column as unique in you table.
when ever you are trying to insert new user, SQL will throw an constraint violation exception if email already exists. you can use that error also for error handling
generally update will take more time compared to get operation So the best method is..
First you have to check is there any row exist with this email ID
String sql = "select email from users where email= ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, "emailId");
ResultSet rs = prepStmt.executeQuery();
if (rs.next()) {
System.out.println("Row with email found");
} else {
// you can write update code here
}
For Unique Email validation, there are two methods:
Method 1:
The first one is to execute the select query and check it, which is not recommended as a solution.
PreparedStatement statement = connection.prepareStatement("select email from users where email= ?");
statement.setString(1, email99);
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
System.out.println("Row with email found");
} else {
// you can write update code here
}
Method 2:
on the DB level, make the email column unique. so whenever a new record is inserted. DB is responsible for checking the unique email address and throw the error. Use the error to display it on the front end.
cheers!!
Method1:
The simplest method is using unique index on column email.
You can not using the solution which looks up email firstly and insert email. Suppose that there are two users submit the email some#email.com. And there does't have the email in your DB.
Both users will get res.next() false, and you will insert two rows with the same email to DB.
If you use the unique index, you will get Exception if there already has the email. You can catch the Exception and return the "duplicate email" message.
See the question catch duplicate exception
If you use Mysql, maybe you can use the ON DUPLICATE KEY.
Method2:
There has a more complicated solution.
If you can not use the unique index, then you can consider this.
You can use the Lock. If you work on distributed system, you should use the distributed lock. You should lock the email. If the thread get the lock, you can check whether there has the target email and then insert into DB.
But if your system just run on one JVM, you can try:
syschronized(email.intern()) {
// check the email whether exists
// if not, insert it.
}
In this case, you will suffer from the large String pool which will affect your GC pause and waste memory.
In fact you can use double-check to optimize the performance. It looks like
emailInDB = fetchEmailFromDB(email);
if (emailInDB == null) {
lock(email);
emailInDB = fetchEmailFromDB(email);
if(emailInDB == null) {
insertIntoDB(email)
} else {
return "the email already exists";
}
} else {
return "the email already exists";
}
So what I'm trying to do is store a username and GUID in a SQLite database. When a new player joins the Bukkit server, the server gets the player's username and generates a GUID. The server gets this GUID and gives it to the player so that he can verify it. The username and GUID are now stored in the SQLite database. If a player joins the server with an unverified GUID, he gets kicked. So I need a way to track whether the GUID is verified or not. That's why the SQLite database contains an integer named 'verified'. If the integer is 0, the GUID is unverified. If it's 1, it's verified. Here's how the table looks like:
CREATE TABLE AUTH (USERNAME CHAR(50) PRIMARY KEY NOT NULL, GUID CHAR(36) NOT NULL, VERIFIED INT NOT NULL)
It doesn't matter whether the SQL statement is correct or not, as long as it gives you a basic understanding of how my table looks like.
So the problem I'm experiencing is with the code that kicks the player if his GUID is unverified/null.
// Check whether player has a GUID
if (playerDatabase.hasGUID(player)) {
// Check whether GUID is verified
if (playerDatabase.isGUIDVerified(player)) {
// ...
}
}
I did a couple of tests and found that the hasGUID boolean always returns false. Here's the code for hasGUID
resultSet = statement.executeQuery("SELECT * FROM AUTH;");
while (resultSet.next()) {
if (resultSet.getString("USERNAME").equalsIgnoreCase(player.getName())) {
if (resultSet.getString("GUID") != null) {
statement.close();
return true;
}
}
}
The above code is surrounded in a try/catch statement. Any mistakes I'm doing in here?
correct your SQL query select * from auth where username = username; and
if (rs.next()){
//ResultSet is not empty
}else {
//ResultSet is empty
}
Searched for an answer to this but can't find anything similar. Checked the questions which may already have my answer as well but again no solution.
So first of all, here is the code which doesn't complete:
Class.forName(DRIVER);
Connection connection = DriverManager.getConnection(URL, USER,
PASS);
Statement statement = connection.createStatement();
e = email.getText();
p = password.getText();
String SQL = "SELECT email, password FROM healthcareProfessional WHERE email = '" + e
+ "' AND password = '" + p + "';";
ResultSet resultSet = statement.executeQuery(SQL);
while (resultSet.next()) {
if (email.getText().equals(resultSet.getString("email"))
&& password.getText().equals(resultSet.getString("password"))) {
Main.applyHomescreenLayout();
} else if (email.getText().equals("") || password.getText().equals("")) {
errorMessage.setText("Incorrect Email.");
errorMessage.setTextFill(Color.RED);
FadeTransition fadeTransition = new FadeTransition(Duration.millis(3000.0), errorMessage);
fadeTransition.setFromValue(3000.0);
fadeTransition.setToValue(0.0);
fadeTransition.playFromStart();
}
}
Everything here works fine provided I enter valid login credentials. However, if I leave the email or password blank and try to log in, no message is displayed and I can't understand why. Can anyone point me in the right direction?
Also, if I remove the connection the below code works perfectly and the message is displayed.
if (email.getText().equals("") || password.getText().equals("")) {
errorMessage.setText("Incorrect Email or Password.");
errorMessage.setTextFill(Color.RED);
FadeTransition fadeTransition = new FadeTransition(Duration.millis(3000.0), errorMessage);
fadeTransition.setFromValue(3000.0);
fadeTransition.setToValue(0.0);
fadeTransition.playFromStart();
}
I have also tried closing the resultset, statement and connection within the if and else if statements, replacing the .equals("") with .isEmpty(), and using separate resultsets, none of which worked.
First of all this check must be before checking Database, i.e. before execution of DB query to check for user credentials.
if (email.getText().equals("") || password.getText().equals("")) {
errorMessage.setText("Incorrect Email.");
errorMessage.setTextFill(Color.RED);
FadeTransition fadeTransition = new FadeTransition(Duration.millis(3000.0), errorMessage);
fadeTransition.setFromValue(3000.0);
fadeTransition.setToValue(0.0);
fadeTransition.playFromStart();
}
You must not allow anyone with no password or no email id to sniff your database check.
Secondly but your DB connection in try catch block and in finally block release all connection objects,statement objects.
Thirdly use prepared statement to protect your system from sql injections.It is not good practice to create query in this way.
https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
Do you get any message when the email and password are not blank but does not match?
It seems that if there is no matching combination the resultSet will be empty and next() will always evaluate as false, completely skipping the while loop.
What I would do (no compiler here, so the code can have mistakes) is:
ResultSet resultSet = statement.executeQuery(SQL);
if (resultSet.next()) {
//No need to re-validate
Main.applyHomescreenLayout();
} else {
//no email|password combination found on database
errorMessage.setText("Incorrect Email.");
errorMessage.setTextFill(Color.RED);
FadeTransition fadeTransition = new FadeTransition(Duration.millis(3000.0), errorMessage);
fadeTransition.setFromValue(3000.0);
fadeTransition.setToValue(0.0);
fadeTransition.playFromStart();
}
This was said before but is always good to be reinforced: take a look at prepared statements to avoid sql injections.
Your else block is essentially unreachable.
Your SQL statement selects only rows in the database table for which the database email field is equal to the text in the email text field, and for which the database password field is equal to the text in the password text field (or PasswordField, presumably).
So if the user leaves either email or password blank, it will select only rows from the database for which email is blank or password is blank, respectively. In that case, for any row in the result set, the test
if (email.getText().equals(resultSet.getString("email"))
&& password.getText().equals(resultSet.getString("password")))
will still evaluate to true, so you won't reach the else block. If there are no such rows in the database table, then you simply get an empty result set and your while loop iterates zero times, so you won't reach the else block (or even the if block) under those conditions either.
I am having trouble with getting my program to run properly. I was able to clear any syntax errors, but now I am having issued with my output.
I have the following statement and the ELSE IF doesn't seem to be working? it always ignores the else if codes. i can't understand the problem with the code.
Can anybody help me?
private void login_btnActionPerformed(java.awt.event.ActionEvent evt) {
Connection con;
PreparedStatement stmt;
ResultSet rs;
try {
//connect to the database
String host = "jdbc:derby://localhost:1537/LoginSystem";
String uName = "root";
String uPass = "root";
con = DriverManager.getConnection(host, uName, uPass);
String user = username_txt.getText();
String pass = passwordField_txt.getText();
String sql = "Select USERNAME,PASSWORD from LOGINSYSTEM where USERNAME = '"+user+"' AND PASSWORD = '"+pass+"'";
stmt = con.prepareStatement(sql);
rs = stmt.executeQuery();
while(rs.next()) {
String s1 = rs.getString(1);
String s2 = rs.getString(2);
if(user.equals(s1) && pass.equals(s2)) {
JOptionPane.showMessageDialog(null, "Login Successfull!");
Account obj = new Account();
obj.setVisible(true);
} else if(!user.equals(s1) && !pass.equals(s2)) {
JOptionPane.showMessageDialog(null, "Login Failed!");
} else if(!pass.equals(s2)) {
JOptionPane.showMessageDialog(null, "Please Enter A Valid Password.");
passwordField_txt.setText(null);
}
}
} catch(SQLException e) {
JOptionPane.showMessageDialog(null, e);
}
}
The query returns matching user and pass values so there is no condition where !user.equals(s1) && !pass.equals(s2) is satisified. Always use PreparedStatement placeholders rather than String concatenation to protect against SQL Injection.
Differentiating the error between an invalid usernames and passwords allows any would-be hacker an insight what information can be used to gain access to the system.
If anything the code should look like
if (rs.next()) {
String s1 = rs.getString(1);
String s2 = rs.getString(2);
// user and pass already match from SQL - no if logic necessary
} else {
// display GENERIC login failure message
}
But storing passwords in a database is a major security flaw so this whole approach is not safe. The typical approach is to store the password using a salt to guard against the use of rainbow tables. To verify the password the same hashing algorithm and salt can be used to compare against what is stored in the database,
First this is subject to a SQL injection attack. Learn about prepared statements, and use the parameter passing feature of prepared statements, to prevent user names like: Little Bobby Tables
Second, your where statement will only return back rows where the user name and password are exact matches to the inputted values. Therefore, comparing a non-null result will be guaranteed to always match, barring some incredibly bizarre database bug.
If you ask me to give you a fruit where the fruit is a red apple, then assuming that I am trusted, when I give you a red apple, checking to see if the apple is not an apple, or that red is not red will result in checking a condition that is never met.
If usernames are forced unique, you can take that matching condition for the password out of the query. Then just query for the username matching condition and get the username and password for that row. This way you can check for incorrect password OR incorrect username more easily. The way it is now the query will only return results when the username and password are correct and you will never enter your else if's.
For some reason the login only works for the last user in the database. I have a while loop, but I think it makes the program to go to the last user. I tried using if statement but then only the first user can log in.
if (username!=null && password!=null) {
pagename = "main";
} else {
username = request.getParameter("username");
password = request.getParameter("password");
while(results.next())
{
if(results.getString(2).equals(password) && results.getString(1).equals(username))
{
pagename="main";
}
else
{
pagename="start";
}
}
}
How is this caused and how can I solve it?
You are copying the entire DB table into Java's memory and doing the comparison in a while loop over all records. You are not aborting the while loop when there's a match with a record, so it continues looping over the remaining records and so the pagename get overridden with "start" everytime.
You need to add a break statement:
if (results.getString(2).equals(password) && results.getString(1).equals(username)) {
pagename="main";
break;
}
Or, better, let SQL do the job it is designed for, selecting and returning exactly the data you need:
preparedStatement = connection.prepareStatement("SELECT id FROM user WHERE username=? AND password=MD5(?)");
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
pagename = "main";
}
else {
pagename = "start";
}
That's more efficient and sensible.
Why would you loop through the whole table to do this? What if you have 1000000 records? You should query the database with WHERE clause passing the username and password parameters and then simply check if there are returned row or not.