Open In App

Authentication with API Key in Java

Last Updated : 13 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Usually, in a web application, we will log in by using a username(email id/login name) with a password. Securely we can do the same by using an APIKey as well. Let us see what is an APIKey. The API key is a unique identifier that authenticates requests and if several users are there, their username or email id can be joined with the current date and a secure code meant only for that project by using the md5 mechanism, we can create APIKey and can maintain in a database. Let us see the ways of creating APIKey and inserting it into the database.

Example Project

MySQL table structure:

-- Sample table named users is available
CREATE TABLE `users` (
  `userId` int(11) NOT NULL AUTO_INCREMENT,
  `loginId` varchar(20) DEFAULT NULL,
  apiKey varchar(255) DEFAULT NULL,
  PRIMARY KEY (`userId`)
);
-- insert 2 records
insert into users (loginId) values ('geeka@gmail.com');
insert into users (loginId) values ('geekb@gmail.com');

 

Now let us see the sample java program for the creation of an API key and updating into the ‘users’ (MySQL) table

Java




import static java.nio.charset.StandardCharsets.UTF_8;
 
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class CreateAndUpdateAPIKey {
    Connection conn;
    // To generate MD5 hashvalue
    public String generateMD5Hashvalue(String userName)
    {
        LocalDate dateObj = LocalDate.now();
        DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("yyyyMMdd");
        String date = dateObj.format(formatter);
 
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        }
        catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException(e);
        }
        String secretPhase
            = "geeks"; // exclusively to set for geeks
        System.out.println("Current Date : " + date);
        System.out.println("Login Id : " + userName);
        System.out.println("Secret Phase : " + secretPhase);
 
        // By using the current date, userName(emailId) and
        // the secretPhase , it is generated
        byte[] hashResult
            = md.digest((date + userName + secretPhase)
                            .getBytes(UTF_8));
        // convert the value to hex
        String password = bytesToHex(hashResult);
        System.out.println("Generated password.."
                           + password);
 
        return password;
    }
    private String bytesToHex(byte[] bytes)
    {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
 
    public static void main(String[] args)
    {
        // let us assume there is a table 'users' available
        // By passing as an argument, we can have that for
        // any table
        new CreateAndUpdateAPIKey("users");
    }
 
    public CreateAndUpdateAPIKey(String tableName)
    {
        try {
            // connecting to mySQL
            Class.forName("com.mysql.jdbc.Driver")
                .newInstance();
            String url
            conn = DriverManager.getConnection(url, "root",
                                               "admin");
            doSelectAndUpdate(tableName);
            conn.close();
        }
        catch (ClassNotFoundException ex) {
            System.err.println(ex.getMessage());
        }
        catch (IllegalAccessException ex) {
            System.err.println(ex.getMessage());
        }
        catch (InstantiationException ex) {
            System.err.println(ex.getMessage());
        }
        catch (SQLException ex) {
            System.err.println(ex.getMessage());
        }
    }
 
    private void doSelectAndUpdate(String tableName)
    {
        doSelect(tableName);
    }
 
    private void doSelect(String tableName)
    {
        String query = null, userName = null;
        // Query the respective table. If multiple tables
        // are possible, then we should have separate if or
        // switch statements
        query = "SELECT * FROM users";
 
        try {
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery(query);
            while (rs.next()) {
                // loginId is the unique column to identify
                // the user
                userName = rs.getString("loginId");
                // Get the MD5 value and get as password
                String password
                    = generateMD5Hashvalue(userName);
                // update the password
                doUpdate(password, userName, tableName);
                System.out.println(userName + ":"
                                   + password);
            }
        }
        catch (SQLException ex) {
            System.err.println(ex.getMessage());
        }
    }
 
    private void doUpdate(String apiKey, String userName,
                          String tableName)
    {
        System.out.print("\n[Performing UPDATE] ... ");
        try {
            Statement st = conn.createStatement();
           
            // Use the generated password for apiKey
            String sqlUpdate = null;
            sqlUpdate = "UPDATE users "
                        + "SET apikey = ? "
                        + "WHERE loginId = ?";
 
            PreparedStatement pstmt
                = conn.prepareStatement(sqlUpdate);
 
            pstmt.setString(1, apiKey);
            pstmt.setString(2, userName);
 
            int rowAffected = pstmt.executeUpdate();
            System.out.println(String.format(
                "Row affected %d", rowAffected));
        }
        catch (SQLException ex) {
            System.err.println(ex.getMessage());
        }
    }
}


On execution of the above program, we can see below the output We can see the API key updation below in MySQL as well.

 

Now let us try to login into the sample by using login id and apiKey. Main important thing is apiKey will be changed on daily basis because of the date. In order to make this happen. this java code needs to be placed as a ‘CRON’ job in Linux servers. We can have a sample JSP page where we should have the provision to key in loginId and apiKey.

HTML




<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Login Form With APIKey</title>
</head>
<body>
    <div align="center">
        <h1>Login Form - API KEY</h1>
        <form action="<%=request.getContextPath()%>/login" method="post">
            <table style="with: 100%">
                <tr>
                    <td>Login</td>
                    <td><input type="text" name="loginId" /></td>
                </tr>
                <tr>
                    <td>APIKEY</td>
                    <td><input type="password" name="apiKey" /></td>
                </tr>
 
            </table>
            <input type="submit" value="Submit" />
             
        </form>
    </div>
</body>
</html>


 

Once the information is received it will be stored in the bean and get validated. Let’s see the validation one. 

LoginWithAPIKeyDao.java

Java




import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import net.gfg.login.bean.LoginBean;
 
public class LoginWithAPIKeyDao {
 
    public boolean validate(LoginBean loginBean)
        throws ClassNotFoundException
    {
        boolean status = false;
 
        Class.forName("com.mysql.jdbc.Driver");
 
        try {
            Connection connection = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/geeksforgeeks?useSSL=false",
                "root", "admin");
            // We have to query the users table with the
            // passed information
            PreparedStatement preparedStatement
                = connection.prepareStatement(
                    "select * from users where loginId = ? and apiKey = ?");
            preparedStatement.setString(
                1, loginBean.getLoginId());
            preparedStatement.setString(
                2, loginBean.getApiKey());
 
            ResultSet rs = preparedStatement.executeQuery();
            // For the given query, if there is a record
            while (rs.next()) {
                status = true; // make the status to true
            }
        }
        catch (SQLException e) {
            // process sql exception
            displaySQLException(e);
        }
        return status;
    }
 
    private void displaySQLException(SQLException ex)
    {
        // for (Throwable e : ex) {
        if (ex instanceof SQLException) {
            ex.printStackTrace(System.err);
            System.err.println(
                "SQLState: "
                + ((SQLException)ex).getSQLState());
            System.err.println(
                "Error Code: "
                + ((SQLException)ex).getErrorCode());
            System.err.println("Message: "
                               + ex.getMessage());
            Throwable t = ex.getCause();
            while (t != null) {
                System.out.println("Cause: " + t);
                t = t.getCause();
            }
        }
        // }
    }
}


and then it will get redirected to the success page or further mechanism

 

Conclusion

In this article, we have seen how to generate APIKey by using the MD5 mechanism and using the loginId/apiKey how to login into an application.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads