当前位置: 首页 > article >正文

别再硬编码密码了!用Java+MySQL实现超市收银系统登录模块(附完整源码)

从零构建安全可靠的超市收银系统登录模块Java与MySQL实战指南超市收银系统作为零售业的核心工具其安全性往往被初学者忽视。想象一下当收银员输入用户名和密码时这些敏感信息如果以明文形式存储在数据库或代码中会带来怎样的风险本文将带你从零开始用Java和MySQL构建一个真正安全可靠的登录模块。1. 为什么硬编码密码是致命错误很多初学者在开发登录功能时为了图方便直接在代码中写入用户名和密码。这种看似简单的做法实际上埋下了巨大的安全隐患。让我们看一个典型的反面案例// 危险示范硬编码验证 if(username.equals(admin) password.equals(123456)) { // 登录成功 }这种代码至少有三大致命问题源代码泄露风险一旦代码被获取所有账户信息立即暴露修改成本高每次修改密码都需要重新编译部署权限管理缺失无法区分不同角色的操作权限更糟糕的是有些开发者虽然使用了数据库但却以明文存储密码-- 不安全的数据表设计 CREATE TABLE users ( username VARCHAR(50), password VARCHAR(50) -- 明文存储密码 );2. 安全登录模块的核心设计2.1 数据库层的安全加固首先我们需要设计一个安全的用户表结构CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password_hash CHAR(64) NOT NULL, -- SHA-256哈希值 salt CHAR(32) NOT NULL, -- 随机盐值 display_name VARCHAR(100), role ENUM(admin, cashier, inventory) NOT NULL, last_login DATETIME, failed_attempts INT DEFAULT 0, is_locked BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;关键安全特性密码哈希使用SHA-256等加密算法存储密码盐值加密为每个用户生成唯一盐值防止彩虹表攻击账户锁定多次失败尝试后自动锁定账户角色权限明确的角色划分便于权限控制2.2 Java实现密码加密在Java中我们可以使用MessageDigest类实现安全的密码哈希import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Base64; public class SecurityUtil { private static final SecureRandom RANDOM new SecureRandom(); public static String generateSalt() { byte[] salt new byte[16]; RANDOM.nextBytes(salt); return Base64.getEncoder().encodeToString(salt); } public static String hashPassword(String password, String salt) { try { MessageDigest md MessageDigest.getInstance(SHA-256); md.update(salt.getBytes()); byte[] hashedPassword md.digest(password.getBytes()); return Base64.getEncoder().encodeToString(hashedPassword); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(加密算法不可用, e); } } }3. 防SQL注入的数据库操作使用PreparedStatement是防止SQL注入的基本要求但我们可以做得更好3.1 改进的DBUtil类public class DBUtil { private static final String DB_URL jdbc:mysql://localhost:3306/supermarket; private static final String DB_USER app_user; private static final String DB_PASSWORD secure_password; private static DataSource dataSource; static { try { HikariConfig config new HikariConfig(); config.setJdbcUrl(DB_URL); config.setUsername(DB_USER); config.setPassword(DB_PASSWORD); config.setMaximumPoolSize(10); config.setConnectionTimeout(30000); dataSource new HikariDataSource(config); } catch (Exception e) { throw new RuntimeException(数据库连接池初始化失败, e); } } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } public static void close(Connection conn, Statement stmt, ResultSet rs) { // 关闭资源的实现 } }关键改进使用连接池HikariCP提供高性能的数据库连接管理专用数据库用户避免使用root账户限制权限资源管理确保所有数据库资源都被正确关闭3.2 安全的用户认证实现public class UserDAO { private static final String SQL_AUTHENTICATE SELECT id, username, password_hash, salt, role, display_name, failed_attempts, is_locked FROM users WHERE username ?; public static User authenticate(String username, String password) throws AuthenticationException { try (Connection conn DBUtil.getConnection(); PreparedStatement stmt conn.prepareStatement(SQL_AUTHENTICATE)) { stmt.setString(1, username); ResultSet rs stmt.executeQuery(); if (!rs.next()) { throw new AuthenticationException(用户名或密码错误); } if (rs.getBoolean(is_locked)) { throw new AuthenticationException(账户已被锁定请联系管理员); } String storedHash rs.getString(password_hash); String salt rs.getString(salt); String inputHash SecurityUtil.hashPassword(password, salt); if (!storedHash.equals(inputHash)) { updateFailedAttempts(rs.getInt(id), rs.getInt(failed_attempts) 1); throw new AuthenticationException(用户名或密码错误); } // 认证成功重置失败计数 updateFailedAttempts(rs.getInt(id), 0); return new User( rs.getInt(id), rs.getString(username), rs.getString(display_name), rs.getString(role) ); } catch (SQLException e) { throw new RuntimeException(数据库错误, e); } } private static void updateFailedAttempts(int userId, int attempts) { // 更新失败尝试次数的实现 } }4. 用户界面与安全实践4.1 控制台登录实现public class LoginConsole { private static final int MAX_ATTEMPTS 3; public static void main(String[] args) { Scanner scanner new Scanner(System.in); int attempts 0; while (attempts MAX_ATTEMPTS) { System.out.print(用户名: ); String username scanner.nextLine(); System.out.print(密码: ); String password scanner.nextLine(); try { User user UserDAO.authenticate(username, password); System.out.println(登录成功! 欢迎, user.getDisplayName()); // 根据角色进入不同系统模块 if (admin.equals(user.getRole())) { AdminConsole.start(); } else { CashierConsole.start(); } return; } catch (AuthenticationException e) { attempts; System.out.println(e.getMessage()); System.out.println(剩余尝试次数: (MAX_ATTEMPTS - attempts)); } } System.out.println(超过最大尝试次数系统退出); System.exit(1); } }4.2 安全最佳实践清单密码策略强制8位以上复杂度定期更换密码禁止使用常见弱密码会话管理设置合理的会话超时注销时清除会话使用HTTPS传输敏感数据日志记录记录所有登录尝试监控异常登录模式定期审计日志5. 进阶安全措施5.1 二次验证实现对于管理员账户我们可以增加短信或邮箱验证public class TwoFactorAuth { public static String generateOTP() { int otp 100000 RANDOM.nextInt(900000); return String.valueOf(otp); } public static boolean verifyOTP(String code, String storedCode) { return code.equals(storedCode); } }5.2 密码重置安全流程public class PasswordResetService { private static final long TOKEN_EXPIRE_HOURS 2; public static String generateResetToken(String username) { // 生成唯一令牌并设置过期时间 } public static boolean isValidToken(String token) { // 验证令牌有效性和过期时间 } public static void resetPassword(String token, String newPassword) { // 安全地重置密码 } }6. 性能与安全的平衡安全措施往往会带来性能开销我们需要找到平衡点安全措施性能影响缓解方案密码哈希中等选择适当强度的算法连接池低合理配置连接数账户锁定低异步记录失败尝试日志记录中等使用异步日志系统在实际项目中我遇到过因为过度加密导致登录响应变慢的情况。后来通过以下优化解决了问题将SHA-512降级为SHA-256仍足够安全使用专门的加密硬件加速对认证请求进行缓存处理7. 完整项目结构与部署建议的项目结构supermarket-cashier/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ ├── com/ │ │ │ │ ├── supermarket/ │ │ │ │ │ ├── auth/ # 认证相关 │ │ │ │ │ ├── dao/ # 数据访问 │ │ │ │ │ ├── model/ # 数据模型 │ │ │ │ │ ├── service/ # 业务逻辑 │ │ │ │ │ ├── util/ # 工具类 │ │ │ │ │ └── Main.java # 入口 │ │ ├── resources/ │ │ │ ├── db/ │ │ │ │ └── migration/ # 数据库迁移脚本 │ │ │ └── application.properties ├── pom.xml部署注意事项数据库隔离收银系统使用独立的数据库实例网络隔离收银终端与后台系统分离部署定期备份自动化数据库备份策略最小权限应用程序使用专用数据库账户8. 常见问题与调试技巧在开发过程中我总结了一些常见问题及解决方法连接池耗尽检查是否有未关闭的连接适当增加连接池大小使用连接泄漏检测认证性能问题// 使用缓存减轻数据库压力 Cacheable(value userCache, key #username) public User getUserByUsername(String username) { // 数据库查询 }密码编码不一致确保所有环境使用相同的编码(UTF-8)在哈希前规范化密码字符串记录详细的错误日志时间不同步问题使用NTP同步服务器时间数据库和应用服务器时区一致在日志中记录带时区的时间戳9. 从开发到生产的安全检查清单在将系统部署到生产环境前请确保[ ] 所有默认密码已更改[ ] 数据库不包含测试账户[ ] 错误消息不泄露敏感信息[ ] 启用了数据库连接加密[ ] 实现了定期密码轮换策略[ ] 配置了适当的防火墙规则[ ] 建立了数据备份机制[ ] 设置了操作审计日志10. 持续改进与学习资源安全是一个持续的过程推荐以下资源保持更新OWASP Top 10了解最常见的Web应用安全风险Java安全编码指南Oracle官方的安全编码实践密码学更新关注被破解的算法和新的安全标准安全社区参与本地安全Meetup或线上论坛在项目中引入自动化安全扫描工具也是不错的选择# 使用OWASP Dependency-Check检查依赖漏洞 mvn org.owasp:dependency-check-maven:check记住没有绝对安全的系统但通过实施这些最佳实践我们可以显著降低风险为超市收银系统构建一个坚固的安全基础。

相关文章:

别再硬编码密码了!用Java+MySQL实现超市收银系统登录模块(附完整源码)

从零构建安全可靠的超市收银系统登录模块:Java与MySQL实战指南 超市收银系统作为零售业的核心工具,其安全性往往被初学者忽视。想象一下,当收银员输入用户名和密码时,这些敏感信息如果以明文形式存储在数据库或代码中,…...

用Python分析波场(TRON)链哈希值:一个数据科学小白的实战入门项目(附完整代码)

Python实战:从零开始分析波场链哈希值的数据科学入门指南 区块链技术正在重塑数字世界的基础架构,而数据分析则是理解这一技术的关键钥匙。对于刚接触区块链和Python的开发者来说,如何将两者结合进行实践往往令人望而生畏。本文将带你从零开始…...

深度解析Draw.io Obsidian插件:5步构建可视化知识管理新范式

深度解析Draw.io Obsidian插件:5步构建可视化知识管理新范式 【免费下载链接】drawio-obsidian Draw.io plugin for obsidian.md 项目地址: https://gitcode.com/gh_mirrors/dr/drawio-obsidian 在当今知识密集型工作环境中,Obsidian已成为众多专…...

解决国密SM2算法实现中的常见报错问题

1. 国密SM2算法报错排查指南 第一次接触国密SM2算法时,我也被各种莫名其妙的报错搞得焦头烂额。记得有次项目上线前,系统突然抛出"Unknown named curve"错误,整个团队排查到凌晨三点才找到问题根源。今天我就把这些年踩过的坑整理出…...

如何永久备份微信聊天记录:WeChatMsg完整解决方案指南

如何永久备份微信聊天记录:WeChatMsg完整解决方案指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeCha…...

如何解决下载速度慢和视频保存难题:Xtreme Download Manager实战指南

如何解决下载速度慢和视频保存难题:Xtreme Download Manager实战指南 【免费下载链接】xdm Powerfull download accelerator and video downloader 项目地址: https://gitcode.com/gh_mirrors/xd/xdm Xtreme Download Manager(简称XDM&#xff09…...

efinance:Python量化交易数据获取的终极解决方案

efinance:Python量化交易数据获取的终极解决方案 【免费下载链接】efinance efinance 是一个可以快速获取基金、股票、债券、期货数据的 Python 库,回测以及量化交易的好帮手!🚀🚀🚀 项目地址: https://g…...

R语言数据清理实战:janitor包的高效管道操作指南

1. 为什么你需要janitor包来清理数据 第一次接触数据清洗的R用户,经常会陷入这样的困境:从Excel导入的数据列名带着奇怪的符号,日期格式乱七八糟,还有大量无意义的空行空列。我曾经花了一整天时间手动调整一个只有200行的数据集&a…...

避开LoRa模块干扰:LLCC68双模块半双工通信的硬件布局与软件避坑指南

避开LoRa模块干扰:LLCC68双模块半双工通信的硬件布局与软件避坑指南 在物联网设备密集部署的场景中,LoRa模块的射频干扰问题常常成为工程师的"隐形杀手"。当两块LLCC68模块的PCB间距小于10cm时,实测显示误码率可能骤增300%&#x…...

从Markdown到专业演示文稿:md2pptx如何重构技术文档的呈现逻辑

从Markdown到专业演示文稿:md2pptx如何重构技术文档的呈现逻辑 【免费下载链接】md2pptx Markdown To PowerPoint converter 项目地址: https://gitcode.com/gh_mirrors/md/md2pptx 你是否曾在深夜加班,只为将一份详尽的技术文档转化为演示文稿&a…...

Toppra实战:机器人运动规划中的时间最优轨迹优化

1. Toppra库的核心价值与应用场景 第一次接触Toppra是在为机械臂设计高速抓取轨迹时遇到的难题。当时用传统方法规划的轨迹要么速度太慢影响效率,要么超出电机负载导致抖动。直到发现这个专门解决时间最优轨迹规划的Python库,才真正体会到什么叫"专…...

如何快速配置Android虚拟定位:FakeLocation终极完整指南

如何快速配置Android虚拟定位:FakeLocation终极完整指南 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation 你是否曾经想要在不暴露真实位置的情况下使用某些应用&#x…...

3个核心技术突破:BDD100K如何重新定义自动驾驶感知训练范式

3个核心技术突破:BDD100K如何重新定义自动驾驶感知训练范式 【免费下载链接】bdd100k Toolkit of BDD100K Dataset for Heterogeneous Multitask Learning - CVPR 2020 Oral Paper 项目地址: https://gitcode.com/gh_mirrors/bdd/bdd100k BDD100K作为自动驾驶…...

别再只把n8n当自动化工具了!手把手教你用它的Agent节点,给飞书做个AI日程新闻播报员

解锁n8n Agent节点的隐藏潜力:打造智能飞书日程新闻播报系统 如果你还在用n8n做简单的数据搬运和定时任务,那就像用智能手机只打电话一样浪费。今天我要分享的这套方案,将彻底改变你对自动化工具的认知——我们不仅让系统自动执行任务&#x…...

如何免费下载百度文库文档:3分钟快速获取完整指南

如何免费下载百度文库文档:3分钟快速获取完整指南 【免费下载链接】baidu-wenku fetch the document for free 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wenku 还在为百度文库的下载限制烦恼吗?想要免费获取学习资料却不知道从何下手&…...

从Windows到GEC6818开发板:手把手教你用VMware+Ubuntu搭建嵌入式交叉编译环境(含SecureCRT连接避坑)

从Windows到GEC6818开发板:零基础搭建嵌入式开发环境的完整指南 刚接触嵌入式开发时,最令人头疼的莫过于搭建开发环境。Windows下写代码、Ubuntu虚拟机编译、最后在GEC6818开发板上运行——这个看似简单的流程,实际操作中却会遇到各种"坑…...

Cisco Packet Tracer 6.2 汉化指南 | 计算机网络学习利器

1. Cisco Packet Tracer 6.2 是什么? 如果你正在学习计算机网络技术,尤其是思科认证相关的课程,那么Cisco Packet Tracer绝对是你不可或缺的实战伙伴。这个由思科官方推出的网络模拟工具,可以让你在电脑上搭建各种网络实验环境&am…...

魔兽争霸3兼容性完整解决方案:WarcraftHelper实用工具指南

魔兽争霸3兼容性完整解决方案:WarcraftHelper实用工具指南 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否还在为魔兽争霸3在现代电…...

告别期刊投稿盲目试错!Paperxie AI 期刊写作助手,一键匹配核心 / SCI 录用标准

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/期刊论文https://www.paperxie.cn/ai/journalArticleshttps://www.paperxie.cn/ai/journalArticles 在学术发表的赛道上,硕博研究生、科研工作者乃至高校教师都面临着同样的痛点:写期…...

2026 论文双降终极榜单:10 大 AI 工具,查重降重 + AIGC 消痕一次通关

毕业季的论文战场,重复率与 AIGC 率已成两大 “生死关”。知网、维普不断升级检测算法,AI 写作痕迹一查一个准,单纯降重已不够,必须双率齐降。本文实测 2026 年主流 10 款学术工具,从Paperxie领衔,覆盖中文…...

期刊论文写作 “开挂” 指南:Paperxie AI,从 0 到 1 搞定学术发表

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/期刊论文https://www.paperxie.cn/ai/journalArticleshttps://www.paperxie.cn/ai/journalArticles 科研人谁没为期刊论文熬过大夜?选题卡壳、结构混乱、语言不达标、投稿反复被拒…… 每一步都…...

【CCNA网络】如何根据传输需求选择多模光纤(MMF)与单模光纤(SMF)?

1. 光纤选型的核心考量因素 第一次接触光纤选型时,我也被各种参数搞得晕头转向。直到有次在数据中心亲眼看到两种光纤的对比测试,才真正理解它们的差异。选择多模光纤(MMF)还是单模光纤(SMF),本…...

AutoSubs完全手册:从零到精通的AI字幕生成终极指南

AutoSubs完全手册:从零到精通的AI字幕生成终极指南 【免费下载链接】auto-subs Instantly generate AI-powered subtitles on your device. Works standalone or connects to DaVinci Resolve. 项目地址: https://gitcode.com/gh_mirrors/au/auto-subs 在视频…...

Windows Defender彻底移除完整指南:3种模式解决系统卡顿与性能问题

Windows Defender彻底移除完整指南:3种模式解决系统卡顿与性能问题 【免费下载链接】windows-defender-remover A tool which is uses to remove Windows Defender in Windows 8.x, Windows 10 (every version) and Windows 11. 项目地址: https://gitcode.com/gh…...

完全免费跨平台音乐播放器LX Music桌面版终极使用指南

完全免费跨平台音乐播放器LX Music桌面版终极使用指南 【免费下载链接】lx-music-desktop 一个基于 Electron 的音乐软件 项目地址: https://gitcode.com/GitHub_Trending/lx/lx-music-desktop 你是否厌倦了商业音乐平台的订阅费用和功能限制?LX Music桌面版…...

工业 AI 产品对比:研发与生产场景选型思路解析

工业 AI 市场产品类型多样,不同方案在场景适配、功能落地、易用性、安全性等方面存在明显差异。企业在选型时,通常聚焦图纸管理、SOP 标准化两大高频场景,对比维度包括场景贴合度、操作门槛、数据安全、扩展能力等。本文结合市场现状&#xf…...

【异常解决】JDK21升级中SecurityException: JCE无法验证BC提供者的深度解析

1. 遇到SecurityException时发生了什么 最近在把项目升级到JDK21的时候,突然遇到了一个让人头疼的异常:SecurityException: JCE cannot authenticate the provider BC。这个错误直接导致我们的加密功能全部瘫痪,整个系统都无法正常启动。刚开…...

电赛小白避坑指南:用STM32F103C8T6+L298N驱动板搞定蓝牙遥控循迹小车的完整硬件清单与接线图

电赛新手实战:从零搭建STM32蓝牙循迹小车的避坑手册 第一次参加电子设计竞赛的新手们,面对桌上散落的STM32开发板、电机驱动模块和各种传感器,往往会有种无从下手的茫然感。去年此时,我也曾盯着L298N驱动板上密密麻麻的接线端子发…...

Move Mouse终极指南:告别电脑自动休眠的完整解决方案

Move Mouse终极指南:告别电脑自动休眠的完整解决方案 【免费下载链接】movemouse Move Mouse is a simple piece of software that is designed to simulate user activity. 项目地址: https://gitcode.com/gh_mirrors/mo/movemouse 你是否厌倦了在线会议时离…...

UE5 UI控件实战指南 —— 从基础到高级布局技巧

1. UE5 UI控件基础入门 第一次打开UE5的UMG编辑器时,看到琳琅满目的控件面板可能会有点懵。别担心,我们先从最基础的几个控件开始,就像学写字要先认识笔画一样。Image和Text这两个控件,基本上每个UI界面都离不开它们。 Image控件就…...