Обычно в веб-приложении мы входим в систему, используя имя пользователя (идентификатор электронной почты/имя для входа) с паролем. Безопасно мы можем сделать то же самое, используя APIKey. Давайте посмотрим, что такое APIKey. Ключ API — это уникальный идентификатор, который аутентифицирует запросы, и если есть несколько пользователей, их имя пользователя или идентификатор электронной почты могут быть объединены с текущей датой и безопасным кодом, предназначенным только для этого проекта, с помощью механизма md5, мы можем создать APIKey и можем поддерживать в базе данных. Давайте посмотрим, как создать APIKey и вставить его в базу данных.
Пример проекта
Структура таблицы MySQL:
-- 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');
Теперь давайте посмотрим пример программы Java для создания ключа API и обновления в таблице «пользователи» (MySQL).
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
=
"jdbc:mysql://localhost/geeksforgeeks?useUnicode=true&characterEncoding=utf-8"
;
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());
}
}
}
При выполнении вышеуказанной программы мы видим ниже вывод. Мы также можем видеть обновление ключа API ниже в MySQL.
Теперь давайте попробуем войти в образец, используя идентификатор входа и ключ apiKey. Главное, что apiKey будет меняться ежедневно из-за даты. Для того, чтобы это произошло. этот java-код необходимо разместить как задание «CRON» на серверах Linux. У нас может быть пример страницы JSP, где у нас должно быть условие для ввода loginId и 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
>
Как только информация будет получена, она будет сохранена в bean-компоненте и проверена. Давайте посмотрим на валидацию.
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();
}
}
// }
}
}
А затем он будет перенаправлен на страницу успеха или другой механизм.
Вывод
В этой статье мы увидели, как сгенерировать APIKey с помощью механизма MD5 и использовать loginId/apiKey для входа в приложение.