I have created a login form using java servlets and jsp's. The login information such as username and password is saved in Database.
My question is that when a user enters the information that my java class fails to find in database I dont get the exception. How could I create an exception if the login data isnt available in Db?
public boolean loginValidator(String e, String p) throws SQLException {
String userName = e;
String password = p;
boolean validate = false;
try{
PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE email = ? and password = ?");
ps.setString(1, userName);
ps.setString(2, password);
ResultSet rst = ps.executeQuery();
while (rst.next()) {
validate = (rst.getString("email").equals(userName)) && ((rst.getString("password").equals(password)));
}}
catch(SQLException ex){
System.out.println(ex.getMessage());
validate = false;
}
return validate;
}
This is actually a method in my java class that validates and send boolean type to a servlet and later servlet decides to direct or restrict the access to application subject to the boolean type returned.
PS: A new learner of javaWeb.
And a learner of SQL, right? Because there is NO exception, if there is no such line in the DB table. The query just returns empty ResultSet. So you have to check, whether the result set is empty or not (and then alternatively check the email and password - but that is IMHO superfluous).
public boolean loginValidator(String userName, String password) {
try{
PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE email = ? and password = ?");
ps.setString(1, userName);
ps.setString(2, password);
ResultSet rst = ps.executeQuery();
return rst.next(); // whether DB contains such record
} catch(SQLException ex){
ex.printStackTrace(); // TIP: use logging
}
return false;
}
Btw. I would strongly recommend you NOT to store plaintext passwords in the DB.
Related
String email = email_register_txt.getText();
String username = username_register_txt.getText();
Statement stmt = db_connection.connect().createStatement();
String sql = "SELECT * FROM user_profile WHERE username=' "+username+" ' OR user_email=' "+email+" ' ";
res = stmt.executeQuery(sql);
if(res.next()) {
if(res.getString("username").equalsIgnoreCase(username)) {
JOptionPane.showMessageDialog(registerPanel, "The username has already been already registered!");
} else if (res.getString("user_email").equalsIgnoreCase(email)) {
JOptionPane.showMessageDialog(registerPanel, "This email address has already been already registered!");
}
} else { ...
Either of those error message appear when i enter the username/email who has already been inserted into the database.
My register work but I think the verify part may be missing something?
You are obviously not showing all the pertinent code or you simply have neglected to place the needed code into your method that should make this work.
A ResultSet is basically a collection of results from your query which you need to iterate through to access all results from that query. A while loop is widely used as the means to iterate through all the results contained within a result set object. I see nowhere in your code where you have declared a ResultSet Object but yet you are trying to utilize one. Perhaps try something like this:
String email = email_register_txt.getText();
String username = username_register_txt.getText();
try {
Connection conn = DriverManager.getConnection("...your jdbc connection string...");
conn.setAutoCommit(false);
String sql = "SELECT * FROM user_profile WHERE username = ? OR user_email = ?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, username);
stmt.setString(2, email);
ResultSet res = stmt.executeQuery();
// Utilize a boolean Flag to indicate whether
// or not the User is registered.
boolean registered = false;
while (res.next()) {
if(res.getString("username").equalsIgnoreCase(username)) {
JOptionPane.showMessageDialog(registerPanel,
"The username has already been already registered!");
registered = true;
break; // Get out of the loop. No more need for it.
}
else if(res.getString("user_email").equalsIgnoreCase(email)) {
JOptionPane.showMessageDialog(registerPanel,
"This email address has already been already registered!");
registered = true;
break; // Get out of the loop. No more need for it.
}
}
// Do what needs to be done if User is NOT registered.
if (!registered) {
...............................
...............................
}
res.close();
stmt.close();
conn.close(); //Close the DB connection
}
catch (SQLException ex) {
ex.printStackTrace();
}
You will notice the use of the PreparedStatement Class. There are a number of benefits for using this class:
1) PreparedStatement allows you to write dynamic and parametric queries.
2) PreparedStatement is faster than Statement in Java.
3) PreparedStatement prevents SQL Injection Attacks in Java
Read more about Why to use Prepared Statements in Java here.
code in update button
String password = new String(oldPass.getPassword());
String newPassword = new String(newPass.getPassword());
String realpass = zz.getText();
String us = z.getText();
if(password.equals(realpass))
{
System.out.println("ok");
String query = "UPDATE user SET password = '"+newPassword+"' WHERE username = '"+us+"'";
try{
Statement st = (Statement) con.prepareStatement(query);
int i = st.executeUpdate(query);
if(i!=0){
JOptionPane.showMessageDialog(null, "Your password is successfully changed!");
}
else{
JOptionPane.showMessageDialog(null, "Ooopps! I guess you should call your programmer. ^^");
}
}catch(Exception e){
System.out.println(e);
}
}
code in log in
Methods m = new Methods();
String pass = new String (password.getPassword());
String user = username.getText();
if(m.logInUser(user, pass)==true){
form2 f = new form2();
f.setUser(user);
f.setPass(pass);
f.setVisible(true);
this.dispose();
}....and so on....
code for method log in user
public boolean logInUser(String user, String pass){ //true = nakarecord na sa database login form
try{
String query = "Select * from user where username = ? && password = aes_encrypt('"+pass+"', 'nicanor')";
PreparedStatement pst = (PreparedStatement) con.prepareStatement(query);
pst.setString(1,user);
ResultSet rs = pst.executeQuery();
if(rs.next()){
return true;
}
else{
return false;
}
}
catch(Exception e){
System.out.println(e);
return false;
}
}//logInUser
it says successfully connected in sql and the database is updated but i cant see the next form that should pop up after i entered the updated password
There are few problems with your code:
(1) In your update() logic, you are using the mix of PreparedStatement and Statement together, rather use always use PreparedStatement to bind the input parameters, otherwise they (statements/queries) are prone to SQL injection attacks.
You can refer the below code with inline comments to bind the input parameters with PreparedStatement:
//Write the SQL query with ? to bind the parameters in PreparedStatement
String query = "UPDATE user SET password = ? WHERE username = ?";
PreparedStatement pstmt = null;
try{
//create the PreparedStatement object
pstmt = con.prepareStatement(query);
//bind the input parameters using setString()
pstmt.setString(1, newPassword);
pstmt.setString(2, us);
//execute the prepare statement now
int i = pstmt.executeUpdate(query);
if(i!=0){
JOptionPane.showMessageDialog(null, "Your password
is successfully changed!");
}
else{
JOptionPane.showMessageDialog(null,
"Ooopps! I guess you should call your programmer. ^^");
}
} catch(Exception e){
System.out.println(e);
} finally {
if(pstmt != null)
pstmt.close();
if(con != null)
con.close();
}
Also, remember that database resources are costly and you need to close the resources in the finally block as shown above, otherwise you will end up with resource leaks.
(2) In your logInUser() logic, you are using && which is incorrect, rather in sql you need to use AND operator as shown below:
String query = "Select * from user where username = ?
AND password = aes_encrypt('"+pass+"', 'nicanor')";
I'm developing login application using java servlet and mysql and I'm getting following error when I'm trying to login by giving username and password.
java.sql.SQLException: Column 'alex' not found.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
at com.mysql.jdbc.ResultSet.findColumn(ResultSet.java:987)
at com.mysql.jdbc.ResultSet.getString(ResultSet.java:5584)
at org.kaveen.login.database.LoginDaoImpl.userValidate(LoginDaoImpl.java:36)
at org.kaveen.login.controller.Login.doPost(Login.java:44)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
..................................
This is my LoginDaoImpl class
public class LoginDaoImpl implements LoginDao {
public String userValidate(LoginBean loginBean) {
String userName = loginBean.getUserName();
String password = loginBean.getPassword();
System.out.println(userName);
System.out.println(password);
String sql = "select username,password from users";
String userNameDB = "";
String userPasswordDb = "";
Connection connection = null;
java.sql.Statement statement = null;
ResultSet resultSet = null;
try {
connection = DbConnecton.setConnection();
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
userNameDB = resultSet.getString(userName);
userPasswordDb = resultSet.getNString(password);
if (userName.equals(userNameDB)
&& password.equals(userPasswordDb)) {
return "Success";
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return "Failed invalid credentials";
}
}
Can any one please explain why I'm getting this error? and how can I fix it?.
You are trying to login with a username called "alex"? here is your error:
userNameDB = resultSet.getString(userName);
When using the method getString on a ResultSet you can specify the column index (starting from 1) of the column in the result, or the column name (in your case the column name is "username"). You are passing the actual username to the method and of course that column does not exist.
try this:
userNameDB = resultSet.getString("username");
What your are doing is very wrong. your query gets all the rows from users table and your are iterating over it.
to correct it you have to pass the name of the column when getting data from result set.
userNameDB = resultSet.getString(userNameColumn);
userPasswordDb = resultSet.getNString(passwordColumn);
but this way is very stupid. you can do this in your database with a simple query.
with this query there is no need for iteration.
select * from users where username_col=username and password_col=password
assuming that you store passwords in raw text which is wrong.
You should prepare a single SQL query to check if your user credentials are matching, looping over a result set can be costly (when number of user is high).
String sql = "select username, password from users where username=:username and password = :pass";
Connection connection = null;
java.sql.Statement statement = null;
ResultSet resultSet = null;
try {
connection = DbConnecton.setConnection();
statement = connection.createStatement();
resultSet= statement.executeQuery(sql);
resultSet.setString("username", username );
resultSet.setString("pass", password );
if (resultSet.hasNext()){ // check if we had found someone with same username and password
return "Success";
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(connection!=null)// finaly remember to close connection if open
connection.close()
}
return "Failed invalid credentials";
I am trying to ensure that when a user enters username & password, authentication is done by checking if input matches some row in the user table. Here is the code so far: It doesn't respond when the login button is click. Please suggest how I can set it right. Thanks
private void dbConnection()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maths_tutor", "root", "jesus");
Statement stmt = conn.createStatement();
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
ResultSet rs = stmt.executeQuery(CHECK_USER);
while(rs.next())
{
String user = txtUser.getText();
String pass = txtPass.getText();
if(user.equals(rs.getString("username")))
{
if(pass.equals(rs.getString("password")))
{
this.dispose();
new AboutTo().setVisible(true);
}
else JOptionPane.showMessageDialog(null, "Invalid Password");
}
else JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
stmt.close();
rs.close();
conn.close();
}
catch(SQLException | ClassNotFoundException er)
{
JOptionPane.showMessageDialog(null, "Exception:\n" + er.toString());
}
}
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
you have passed username & password in sql query so it go in while block only if username And password will match ...
you supposed to make sql querylike this
String CHECK_USER = "SELECT * FROM records";
or you can use if block like this
if(rs.next()
{
//login successfull code
}
else
{
//login fail
}
Basically, the logic is wrong.
What you are doing is approximately this.
Get a username and a password from the user.
Ask the database for all records for which the user name is matches the supplied username and the password matches the supplied password.
For each such record:
Test if the user name matches, and open a dialog if it doesn't match. That won't happen ... because you only selected records with that user name.
Test if the password matches, and open a dialog if it doesn't match. That won't happen ... because you only selected records with that password.
What you really ought to be doing is:
Get a username and a password from the user.
Select the records that match the user name and password.
Print a message if the number of records that you matched is zero.
I should also point out some other things:
Popping up a dialog box to tell the user his user name / password are wrong is beside the point. What you really need to do is tell something else in your server that the login failed.
When the user gets just the username or just the password incorrect, you should not offer him any clues that one was correct. Doing that makes it easier for "the bad guy" to work out the correct combination.
Storing passwords in clear in a database is Bad Practice. Best practice is to store seeded hashes of the passwords ... and use a cryptographically strong hashing function.
You forgot to call getText() on txtUser and txtPass.
This is how you could fix your query:
String CHECK_USER = "SELECT * FROM records WHERE username = '" + this.txtUser.getText() + "' AND password = '" + this.txtPass.getText() + "'";
You should note that concatenation of raw input text to queries will open vulnerability to SQL injection. You should use PreparedStatement instead so that the input text is properly escaped.
The following is a way to implement this properly, however lacks the following things that should be of concern to you:
You are storing passwords in clear text. You should use a hashing function such as SHA-1.
Every authentication will result in a new connection to the database. You should probably use a proper connection pool.
.
private boolean authenticate() throws SQLException {
String dbUrl = "jdbc:mysql://localhost:3306/maths_tutor";
// This query will simply count the matching rows, instead of actually selecting
// them. This will result in less bandwidth between your application and the server
String query = "SELECT count(*) AS num_records FROM records WHERE username = ? AND password = ?";
// Obtaining the username and password beforehand could perhaps make it more clear
// and prevent errors instead of pulling the data every time you need it
String username = txtUser.getText();
String password = txtPass.getText();
// The try-with-resources block will make sure the resources are closed once we are done with
// them. More information available at
// http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
try (
// Open database connection
Connection conn = DriverManager.getConnection(dbUrl, "root", "jesus");
// Prepare the statement
PreparedStatement stmt = conn.prepareStatement(query)
) {
// Set the username and password for the SQL statement
stmt.setString(1, username);
stmt.setString(2, password);
// Execute the query in a try block, to ensure that the resources
// will be released
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
// If we got 1 or more matches, this means we successfully
// authenticated. Otherwise, we failed authentication.
return rs.getInt("num_records") > 0;
}
}
}
// Failed authentication.
return false;
}
// Rename this to something meaningful according to your application
private void doAuthentication() {
try {
if (authenticate()) {
// Do successful authentication handling
this.dispose();
new AboutTo().setVisible(true);
} else {
// Do failed authentication handling
JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
} catch(SQLException er) {
// Do error handling
JOptionPane.showMessageDialog(null, "Exception:\n" + er.toString());
}
}
The possible error would be near this line
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maths_tutor", "root", "jesus");
first make sure you have set the classpath and added the mysql driver to the project
second I would the following instead of the above, in fact why do you make things to much complex?!
java.sql.Driver _dr=new com.mysql.jdbc.Driver();
java.util.Properties _pr=new java.util.Properties();
_pr.setProperty("user","root");
_pr.setProperty("password","jesus");
Connection conn = _dr.connect("jdbc:mysql://localhost:3306/maths_tutor", _pr);
and the last thing is beware about using this like of code
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
so here the system is ready for injection.
so the good way would be like this, using parameters.
String CHECK_USER = "SELECT * FROM records WHERE username = ? AND password = ?";//this will avoid sql injection
java.sql.PreparedStatement _st=conn.prepareStatement(CHECK_USER);
_st.setString(1, this.txtUser);
_st.setString(1, this.txtPass);
EDIT :by the way, there is no need to iterate over result set! simple just call the next() method, if it returns true, so it means user has entered correct user/pass, else otherwise.
ResultSet rs = stmt.executeQuery(CHECK_USER);
if(rs.next()){/*user exist*/
this.dispose();
new AboutTo().setVisible(true); }
else{
JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
string query = "SELECT count(*) FROM [dbo].[login1] WHERE username='" + username.Text + "' and password='" + password.Text + "'";
SqlDataAdapter sda = new SqlDataAdapter(query, con);
DataTable dt = new DataTable();
sda.Fill(dt);
if (dt.Rows[0][0].ToString() == "1")
{MessageBox.Show("YEAH");}
I am a beginner in using Java and MS Access.
Basically, I need to pass a username and a password (which is encrypted with MD5) and compare it with the data in my database table. If it is found, it should return a Boolean value true.
I get the following error message:
ERROR: java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]General error Unable to open registry key Temporary (volatile) Ace DSN for process 0x3b0 Thread 0xfd4 DBC 0x5a91fcc
This is my function for checking passwords:
private boolean logChck(String username, String password)
{
String query;
boolean login = false;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String filename = "D:/Sand/program/JavaNetbeans/AllCodesHere/TestingCode/src/TestingCode/HotMan2.accdb";
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=";
database+= filename.trim() + ";DriverID=22;READONLY=true}";
connection = DriverManager.getConnection( database ,"","");
query = "SELECT (StfFirName, StfPassword) FROM Staff WHERE (StfFirName = ? AND StfPassword = ?)";
PreparedStatement ps = connection.prepareStatement(query);
ps.setString(1, username);
ps.setString(2, password);
ps.executeQuery();
ResultSet rs = ps.executeQuery();
String checkUser = rs.getString(1);
String checkPass = rs.getString(2);
if((checkUser.equals(username)) && (checkPass.equals(password)))
{
login = true;
}
else
{
login = false;
}
connection.close();
}
catch (Exception err) {
System.out.println("ERROR: " + err);
}
return login;
}
Seems like a permissions issue - check out this suggestion from MS support:
http://support.microsoft.com/kb/295297
Pasting relevant sections from there, as proposed in #minitech's comment:
Cause:
The account that is being used to access the page does not have access to the HKEY_LOCAL_MACHINE\SOFTWARE\ODBC registry key.
Resolution:
Start Registry Editor (Regedt32.exe).
Select the following key in the registry: HKEY_LOCAL_MACHINE\SOFTWARE\ODBC
On the Security menu, click Permissions.
Type the required permissions for the account that is accessing the Web page.
Quit Registry Editor.
Multiple things here.
It's not a password problem; it's a general connection problem. There is something about the filename and database name string workup that doesn't look right. Are the slashes going in the right direction? Create a helloWorld program with just the connection string and get that running first.
You don't need to call executeQuery() twice:
ps.executeQuery(); // get rid of this one
ResultSet rs = ps.executeQuery(); // leave this one.