web application servlet to query and display user information from mysql - java

I need to perform a task for a webpage application, that is to have a page to display the client's information by querying for them
via the client's session id (or some other method) and do a mySQL query into my membership database.
The sequence should be as follows:
1. client logs in
2. compare of client's password and membership database, if match, client will be able to access some pages
3. one of these accessible pages(mentioned in 2)in will contain a link which will then query for the client's information in membership database
4. queried rows(results) will be displayed in the webpage with proper css
just a disclaimer, I am a total beginner at java
Membership database
table's name = member
id | first name | last name | address | telephone number
I have already created and setup a jdbc connection to database:
public void init () throws ServletException {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/membership","root","");
stmt = conn.createStatement();
} catch (ClassNotFoundException ex) { // for Class.forName()
ex.printStackTrace();
} catch (SQLException ex) { // for getConnection()
ex.printStackTrace();
}
}
String query = "SELECT * FROM member WHERE xxx ";
ResultSet rset = stmt.executeQuery(query);
my question is: how do i grab the necessary rows for my problem here? and how should i approach to solve this question?
many thanks for your advice

"my question is: how do i grab the necessary rows for my problem here?"
Use your ResultSet object (rset). Then retrieve any columns you need.
Something similar to this:
while (rs.next()) {
int ID = rs.getInt("id");
String fName = rs.getString("first_name");
String lName = rs.getString("last_name");
String address = rs.getString("address");
String phone = rs.getString("telephone_number");
}

First, I strongly recommend you have no spaces in your column names (eg use '_' instead).
What are your user credentials for logging in? I imagine it's username or email_address as well as password. Whatever the first part of that is (eg username) you could use that as the primary key on your member table. So after they've logged in, you already have username and that forms the 'where' clause in your SQL query. (If they log in with email_address, everything works the same, using that in place of username.)
So the steps are
Take username + password from user
Select count of rows matching that pair
If count == 1 then they're authenticated, otherwise reject
Select other fields matching username
Display to user
Don't store passwords plaintext, so whatever transform you apply for storing them, also apply that to the given password before doing #2. If you choose to have username not be a primary key, ensure you make it at least 'unique' via a constraint.

Related

How can I validate customer login details by checking if they are in my derby database?

I have a registration page where customers sign up and make an account. The account details are stored in an Apache derby database. There is an option for customers with existing accounts to log in to the webpage, how can I cross check that they have an account before allowing access to the site?
Below is the code I used to store the details in the dB. I am unsure how I can validate the users and have found nothing helpful online. Thanks in advance.
//using get parameter to get values from index.jsp
String fn=request.getParameter("firstname");
String ln=request.getParameter("lastname");
String ad=request.getParameter("address");
String em=request.getParameter("email");
String ph=request.getParameter("phone");
String ps=request.getParameter("password");
String conps=request.getParameter("confirmpass");
//connecting to dB
Connection conn=DriverManager.getConnection("jdbc:derby://localhost:1527/login","reg","reg");
Statement st=conn.createStatement();
//inserting values into dB
int i=st.executeUpdate("insert into login values('"+fn+"','"+ln+"','"+ad+"','"+em+"','"+ph+"','"+ps+"','"+conps+"')");
This code snippet can be used to check data is present in table, based on identifier like email -
String em=request.getParameter("email");
// Create a PreparedStatement object 1
PreparedStatement pstmt = con.prepareStatement(
"SELECT count(*) FROM login WHERE email=?");
pstmt.setString(1,em); // Assign value to input parameter 2
ResultSet rs = pstmt.executeQuery();
rs.next(); //Moving the cursor to the last row 3
System.out.println("Email id "+ em + " is present in table for " + rs.getInt("count(*)")+" times");

Setting up user authentication in java with JDBC

I'm currently creating the login functionality of a java web application just using java and JDBC. What built in java libraries are there to make the authentication process easier. I am able to query my PostgreSQL database and retrieve user information such as their password and username but I do not want to store it in plain text.Any tips would be great and o yeah I'm not using spring, which I see there is plenty for.
Generally, password matching is done by storing a one-way hash of the password, instead of storing the password itself as plain text. When someone tries to log in, your application generates a one-way hash of the password the user has entered, and checks whether it matches any of the hashes stored in the database.
Hashing is done with the MessageDigest class:
byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8);
byte[] passwordHash;
try {
passwordHash = MessageDigest.getInstance("SHA-256").dist(passwordBytes);
} catch (NoSuchAlgorithmException e) {
// It should be impossible to get here, since SHA-256 is
// a standard algorithm supported by all Java runtimes.
throw new RuntimeException(e);
}
The password column in your database should be defined as a binary type, like VARBINARY. Then you can store the bytes directly:
try (PreparedStatement statement =
connection.prepareStatement(
"INSERT INTO users (name, passwordhash) VALUES (?, ?)")) {
statement.setString(1, name);
statement.setBytes(2, passwordHash);
statement.executeUpdate();
}
You can check whether a login attempt matches in a similar manner:
try (PreparedStatement statement =
connection.prepareStatement(
"SELECT name, email, phone FROM users"
+ " WHERE name = ? AND passwordHash = ?")) {
statement.setString(1, enteredName);
statement.setBytes(2, enteredPasswordHash);
ResultSet results = statement.executeQuery();
if (!results.next()) {
throw new MyAppInvalidLoginException("No matching login found.");
}
String name = results.getString(1);
String email = results.getString(2);
String phone = results.getString(3);
}
I’m not a security expert, so I will leave it to people with expertise in that area to comment on whether SHA-256 is sufficiently secure for general needs.

How to prepare a string in java that will eventually passed into SQL for a search

This is what I am trying to do
The user enters a string. This gets passed into a java program which then run a query against sql server and tries to find the records where this string occurs. The query that eventually runs against the sql server is something like this
Select * from users where name like '*userPassedInText*'
The problem I have is that if this string has certain characters such as ' the query breaks. I know the ideal way to do this is to use
PreparedStatement statement= con.prepareStatement (myStatement );
But for certain reasons I have to pass in a string. Having said that is there any utility in java that prepares a string to be sent to SQL server?
To answer your immediate question: you simply need to replace all "single quote" characters with TWO single quote characters:
String original ="it's a problem when you have a single quote in SQL params"; // String contains a single quote
String escaped = original.replaceAll("'","''"); // replace all single quotes with 2 single quotes
But I cry for you not to simply take whatever the user passes in (especially given that your variable has the name userPassedInText!!). I would strongly urge everyone to read this:
https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java
... because if you just take whatever the user types in, then they can type in "some text with single quotes' OR 1==1". And you SQL will return ALL records from your DB table. You definitely want to use preparedStatements. And, as a bonus, you won't have to manually replace single quotes with two single quotes.
i think u could try this way, creating a connection, and giving the query by prepareStatement method:
try {
String url = "jdbc:odbc:databaseName";
String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
String user = "guest";
String password = "guest";
Class.forName(driver);
Connection connection = DriverManager.getConnection(url,user, password);
String changeLastName = "UPDATE authors SET lastname = ? WHERE authid = ?";
PreparedStatement updateLastName = connection.prepareStatement(changeLastName);
updateLastName.setString(1, "Martin"); // Set lastname placeholder value
updateLastName.setInt(2, 4); // Set author ID placeholder value
int rowsUpdated = updateLastName.executeUpdate(); // execute the update
System.out.println("Rows affected: " + rowsUpdated);
connection.close();
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe);
} catch (SQLException sqle) {
System.err.println(sqle);
}
here original link: http://www.java2s.com/Code/JavaAPI/java.sql/ConnectionprepareStatementStringsql.htm

In this program, I have to set already existing value for ssn in where clause (ie: in setString (3, ) )

public void UpdateCustomer(Customer customer) throws CustomerHomeException, ClassNotFoundException{
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:Mydb";
String user = "user1";
String password = "password";
Connection con = DriverManager.getConnection(url,user,password);
PreparedStatement smt= con.prepareStatement("update customer SET ssn = ? customer_name = ? where ssn = ?");
if(getCustomer.equals(customer.getSocialSecurityNumber()))
smt.setString(1,customer.getSocialSecurityNumber());
smt.setString(2, customer.getName());
smt.setString(3, customer.);
smt.executeUpdate();
smt.close();
con.close();
}
catch (SQLException e){
throw new CustomerHomeException("Failed to create CustomerHome", e);
}
}
but I am confused how can i retrieve value for existing ssn. Also I have a method getCustomers to retrieve a particular customer separately. Will that help
I recommend that you revisit your database model. You are using SSN as a primary-key (based on you WHERE clause), but then you're trying to update it. It is EXTREMELY poor practice to update primary keys (ref: https://stackoverflow.com/a/3838649/2065845). If you introduce some other key value (an auto-incrementing ID perhaps?), then you'll be able to modify your update statement's WHERE clause to use that ID, and the fact that you no longer have the old SSN becomes unimportant.
Barring that, you'll either need to modify your method signature to include the old SSN, or you'll need to execute a SELECT with some other value to get the old SSN (though, if you can do that, I have to wonder why you don't just use that in the WHERE clause of your UPDATE statement).

Need some modification in my code

This is a small part of the application where user can register any number of employees and employee id is generated by using a while loop....As i close the application & start filling the data again in second round...the value of employee id empid resets to zero. Well, as long as the application is running, i get the desired o/p i.e. a unique id is allotted to every employee. I dont want empid's value to start from 0 whenever i start the application. Need alternatives and/or any modification. Code is provided here
int empcount=0;
public void actionPerformed(ActionEvent ae) {
//---------------------If user wants to add data
if(ae.getActionCommand()=="ADD EMPLOYEE") {
System.out.println("ADDING");
try{
empcount=empcount+1;//----------------will assign employees with unique emp id
//--------------------returns the text in name field to variables
String s_name=name.getText();
int s_code=empcount;
String s_dept=dept.getText();
String s_ph=ph.getText();
String s_bg=bg.getText();
String s_add=add.getText();
String s_date=date.getText();
PreparedStatement st=null;
Connection con = null;
Class.forName("org.hsqldb.jdbcDriver");
con = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/", "SA", "");
st=con.prepareStatement("Insert into EmpReg (emp_name,emp_code,emp_ph,emp_bg,emp_add,emp_date,b_id) values(?,?,?,?,?,?,?)");
//---------------------parameters and respective values, passed to the SQL statement
st.setString(1,s_name);
st.setInt(2,s_code);
st.setString(3,s_ph);
st.setString(4,s_bg);
st.setString(5,s_add);
st.setString(6,s_date);
st.setString(7,s_dept);
st.execute();
JOptionPane.showMessageDialog(null,"Data is inserted into the database");
JOptionPane.showMessageDialog(code, "employee code"+ empcount+"");
con.close();
}
catch(Exception Ee){
System.out.println(Ee);
}
}
}
});
The standard SQL way of doing this, is having an "autoincrement" primary key (emp_code), for hsqldb see IDENTITY.
In the SQL INSERT statement leave out the primary key. Now the database generates a unique new key.
After the execution, you can retrieve the generated primary key from the statement with getGeneratedKeys.
This ensures that two parallel processes will not mess up the primary keys.
Why don't you create a field in your DB, that is set to autoIncrementTrue and maybe use it as ID as well. You can also use this field as Employee-Number.
You can check this Link for more Information: http://www.w3schools.com/sql/sql_autoincrement.asp
The generated number will increment every time you insert a new Employee.
You could use a DB like Oracle, MySQL, PostGre and use a Sequence or auto generated ID Column to do that for you

Categories

Resources