上一篇
场景引入:
凌晨2点,你盯着屏幕里那个总报"密码错误"的Java项目抓狂😫——明明数据库里有用户数据,但登录功能死活不认,别慌!今天我们就用最接地气的方式,手把手实现MySQL数据库连接 + 用户认证系统,让你彻底告别这种抓马时刻!
环境配置
caching_sha2_password
加密) 创建测试数据库
CREATE DATABASE auth_system; USE auth_system;
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(100) NOT NULL, -- 实际存储加密后的值 email VARCHAR(100) UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
---
## 🔌 核心代码四步走
### 第一步:建立数据库连接(含2025年新特性)
```java
import java.sql.*;
public class DatabaseConnector {
private static final String URL = "jdbc:mysql://localhost:3306/auth_system?useSSL=false&serverTimezone=UTC";
private static final String USER = "your_username";
private static final String PASSWORD = "your_password";
public static Connection getConnection() throws SQLException {
// Java 17+ 推荐写法
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
💡 2025小贴士:
Class.forName
import java.security.SecureRandom; import java.util.Base64; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class PasswordUtils { private static final int ITERATIONS = 65536; private static final int KEY_LENGTH = 256; private static final SecureRandom RANDOM = new SecureRandom(); public static String hashPassword(String password, byte[] salt) { try { PBEKeySpec spec = new PBEKeySpec( password.toCharArray(), salt, ITERATIONS, KEY_LENGTH ); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); byte[] hash = factory.generateSecret(spec).getEncoded(); return Base64.getEncoder().encodeToString(hash); } catch (Exception e) { throw new RuntimeException("密码加密失败", e); } } public static byte[] generateSalt() { byte[] salt = new byte[16]; RANDOM.nextBytes(salt); return salt; } }
🚨 安全警告:
public class UserDao { public boolean register(String username, String password, String email) { String sql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)"; byte[] salt = PasswordUtils.generateSalt(); String hashedPassword = PasswordUtils.hashPassword(password, salt); try (Connection conn = DatabaseConnector.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, username); stmt.setString(2, hashedPassword + ":" + Base64.getEncoder().encodeToString(salt)); stmt.setString(3, email); return stmt.executeUpdate() > 0; } catch (SQLException e) { if (e.getErrorCode() == 1062) { System.out.println("⚠️ 用户名/邮箱已存在"); } return false; } } }
📌 存储技巧:
将盐值和哈希密码用冒号拼接存储,格式:哈希值:Base64盐值
public class AuthService { public boolean login(String username, String password) { String sql = "SELECT password FROM users WHERE username = ?"; try (Connection conn = DatabaseConnector.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, username); ResultSet rs = stmt.executeQuery(); if (rs.next()) { String[] storedData = rs.getString("password").split(":"); String storedHash = storedData[0]; byte[] salt = Base64.getDecoder().decode(storedData[1]); String inputHash = PasswordUtils.hashPassword(password, salt); return storedHash.equals(inputHash); } return false; } catch (SQLException e) { e.printStackTrace(); return false; } } }
连接池耗尽
// 用完必须关闭连接! try (Connection conn = DatabaseConnector.getConnection()) { // 操作代码 } // 这里会自动调用conn.close()
SQL注入防护
PreparedStatement
代替字符串拼接 密码重置漏洞
CREATE INDEX idx_username ON users(username); CREATE INDEX idx_email ON users(email);
最终效果:
输入java -jar your_app.jar
启动后,你将获得:
✅ 防注入的注册/登录功能
✅ 军工级密码存储方案
✅ 可扩展的数据库架构
现在你可以放心地去睡觉了,再也不用担心半夜被登录bug叫醒!😴💤
(本文代码实测通过,环境:Java 17.0.9 + MySQL 8.3.0,2025年8月验证)
本文由 集小 于2025-08-01发表在【云服务器提供商】,文中图片由(集小)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/508684.html
发表评论