JavaWeb HTTP 基本认证(Basic Authentication)的示例代码(仅供学习)
使用到的技术:JDBC ,Servlet,Tomcat
使用到的数据库:MySQL
前台需要通过 JavaScript 或类似的脚本语言来获取用户提供的用户名和密码,并将其构造成基本认证的信息,然后发送到后台进行处理。
以下是一个示例代码,展示了如何使用 JavaScript 获取用户提交的用户名和密码,并将其作为基本认证信息发送到后台:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>student</title>
</head>
<body>
<form id="loginForm" method="post">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
<br>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required>
<br>
<button type="button" onclick="submitForm()">登录</button>
</form>
<div id="result"></div>
<script>
function submitForm() {
debugger;
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var encodedUsername = encodeURIComponent(username);
var encodedPassword = encodeURIComponent(password);
// 构造认证信息
var auth = btoa(encodeURIComponent(encodedUsername) + ":" + encodeURIComponent(encodedPassword));
var authHeader = "Basic " + auth;
// 发送认证请求
var xhr = new XMLHttpRequest();
xhr.open("GET", "/xmm/servlet/HelloWorldServlet");
xhr.setRequestHeader("Authorization", authHeader);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
// 登录成功,执行后续操作
document.getElementById("result").textContent = xhr.responseText;
} else if (xhr.readyState === XMLHttpRequest.DONE) {
// 登录失败,显示错误信息
document.getElementById("result").textContent = "登录失败:" + xhr.status;
}
};
xhr.send();
}
</script>
</body>
</html>
可以使用 Java 中的 Base64 类对包含用户名和密码的 Base64 字符串进行解码。
解析出了用户名和密码的字符串,可以进一步处理和使用这些值,例如进行身份验证或执行其他逻辑操作。
以下是一个示例代码,展示了如何解析用户名和密码,并进行基本的身份验证:
package com.dljd.studeyone;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.Base64;
public class HelloWorldServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取请求头中 Authorization 值
String authorizationHeader = request.getHeader("Authorization");
// 判断Authorization是否为空,以及是否以"Basic "开头
if (authorizationHeader != null && authorizationHeader.startsWith("Basic ")) {
// 解析Authorization中的身份验证信息
String base64Credentials = authorizationHeader.substring("Basic ".length());
byte[] credentialBytes = Base64.getDecoder().decode(base64Credentials);
String credentials = new String(credentialBytes);
// 解析账户和密码
String[] parts = credentials.split(":");
String encodedUsername = parts[0];
String encodedPassword = parts[1];
// 将 url 编码的用户名和密码解码
String username = URLDecoder.decode(encodedUsername, StandardCharsets.UTF_8);
username = URLDecoder.decode(username, StandardCharsets.UTF_8);
String password = URLDecoder.decode(encodedPassword, StandardCharsets.UTF_8);
// 调用身份验证逻辑,判断用户是否有效
if (isValidUser(username, password)) {
// 用户有效,向客户端返回"登录成功!"
response.getWriter().write("登录成功!");
} else {
// 用户无效,向客户端返回"登陆失败!"
response.getWriter().write("登陆失败!");
}
}
}
/**
* 检查用户是否有效
*
* @param username 用户名
* @param password 密码
* @return 如果用户有效,返回true;否则返回false
*/
private boolean isValidUser(String username, String password) {
try (
Connection connection = getConnection();
PreparedStatement preparedStatement = createPreparedStatement(connection, username, password);
ResultSet resultSet = preparedStatement.executeQuery()) {
return resultSet.next(); // 如果结果集中有匹配的记录,则说明用户有效
} catch (SQLException e) {
e.printStackTrace();
return false; // 发生异常时,默认返回 false
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* 获取数据库连接
*
* @return 数据库连接对象
* @throws SQLException 如果获取连接时发生异常
*/
private Connection getConnection() throws SQLException, ClassNotFoundException {
ServletContext servletContext = this.getServletContext();
String className = servletContext.getInitParameter("className");
String url = servletContext.getInitParameter("url");
String user = servletContext.getInitParameter("user");
String password = servletContext.getInitParameter("password");
//注册驱动
Class.forName(className);
return DriverManager.getConnection(url, user, password);
}
/**
* 创建预编译的 SQL 语句对象
*
* @param connection 数据库连接
* @param username 用户名
* @param password 密码
* @return 预编译的 SQL 语句对象
* @throws SQLException 如果创建预编译语句对象时发生异常
*/
private PreparedStatement createPreparedStatement(Connection connection, String username, String password) throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement("SELECT 1 FROM gspuser WHERE username = ? AND password = ?");
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
return preparedStatement;
}
}
效果展示