欢迎光临
我们一直在努力

登录注册模块

登录注册是管理系统类毕设里几乎躲不开的模块,看上去只是两张表单,真正卡人的地方集中在三处:密码怎么存、登录态怎么带、前后端字段怎么对齐。这篇按「表设计 → 密码 → 会话 → 接口约定 → 联调」的顺序给做法和取舍,讲的是判断依据,不是可以直接套用的项目代码。

适用范围:Spring Boot 3.x + MyBatis-Plus + MySQL 8,前端不限框架。

一、表先定下来:两张表够用

很多人一上来就画五张表(用户、角色、权限、用户角色、角色权限),做到一半发现业务里根本没有多角色,余下四张表全是空转。判断依据很简单:如果你的系统只有「管理员」和「普通用户」两种身份,权限写进用户表的一个字段就够,不必拆角色表。

用户表的字段可以这样定:

CREATE TABLE sys_user (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
username VARCHAR(32) NOT NULL COMMENT '登录名',
password_hash VARCHAR(100) NOT NULL COMMENT 'BCrypt 结果约 60 位,留余量',
nickname VARCHAR(32) DEFAULT NULL COMMENT '显示名',
role VARCHAR(16) NOT NULL DEFAULT 'USER' COMMENT 'ADMIN / USER',
status TINYINT NOT NULL DEFAULT 1 COMMENT '1 正常 0 停用',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_username (username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

username 上的 uk_username 别省。注册接口靠它兜住重复注册,否则并发下两个人能注册出同一个登录名,后面登录时「查到两条」的异常很难查。password_hash 长度给到 100,是因为 BCrypt 输出 60 位,换 Argon2 会更长,留余量比事后改表省事。

二、密码存储:差别不在「高级」,在验证成本

做法库被导出后的后果说明
明文 全部账号直接暴露 任何场景都不该出现
MD5 + 固定盐 可被彩虹表批量还原 MD5 计算太快,反而方便离线爆破
BCrypt / Argon2 逐个爆破的成本被抬高 内置随机盐,可调 cost

用 Spring Security 的 crypto 模块就够,不必引入整个安全框架:

// 依赖:org.springframework.security:spring-security-crypto
PasswordEncoder encoder = new BCryptPasswordEncoder();

// 注册:只存哈希
String hash = encoder.encode("123456");

// 登录:用 matches 比对,不要自己拼字符串比
boolean ok = encoder.matches("123456", hash);

注意 BCrypt 每次 encode 结果都不一样(盐随机),所以不能用等号比较两次哈希值,这一点是初学者最常见的误判。

三、登录态:Session 与 Token 的取舍

维度SessionJWT Token
服务端是否存状态 存 不存
前后端分离 / 跨域 要配 Cookie 与 CORS 放请求头即可
强制失效 删 Session 即可 需要额外黑名单或短有效期
实现成本 低(单机) 略高,但联调省心

学生项目大多是单机部署、前端跑在另一个端口,走 JWT 更省事;代价是无法即时强制失效,只能靠短有效期加刷新。如果系统里有「管理员封禁账号」这类需求,封禁后还得在拦截器里查一次用户状态,光靠 token 自证是不够的。

四、接口清单与四条约定

接口方法路径说明
注册 POST /api/auth/register 校验重名,返回新用户 id
登录 POST /api/auth/login 返回 token
当前用户 GET /api/auth/me 靠 token 解析出身份
退出 POST /api/auth/logout 服务端清缓存或前端删 token

四条约定,联调阶段能省掉大量返工:

  • 统一返回体,形如 {code, message, data},前端只解析一种结构;
  • 业务错误用 code 区分,不要动不动返回 HTTP 500;
  • 登录态统一放请求头 Authorization: Bearer <token>;
  • ID 用字符串传给前端。Long 超过 2^53 时 JS 会丢精度,页面上的 id 看着没错,回传后就变成另一个数。
  • public record Result<T>(int code, String message, T data) {
    public static <T> Result<T> ok(T data) { return new Result<>(0, "ok", data); }
    public static <T> Result<T> fail(int code, String message) { return new Result<>(code, message, null); }
    }

    五、联调最常卡的三处

  • 前端把 HTTP 200 当成成功,实际响应体里 code 是 401。判断口径要统一成「先看 code,再看 status」。
  • Cookie 方案下跨域没带 credentials,后端 Set-Cookie 被浏览器丢掉,表现是「登录成功但刷新就掉线」。
  • 前端在提交前对密码做了 trim 或二次加密,后端 matches 自然失败。密码原样传输,加密只发生在服务端。
  • 收尾一句:这个模块的价值不在「能登录」,而在「错了能定位」。把返回体、错误码、请求头三样先统一,后面的模块都是同一套模板。

    (本文由 AI 辅助整理框架与措辞,技术要点与命令均经本人实测核对。)
    如果卡在同样的问题上,可以留言说清报错和版本,我按技术问题帮你判断。

    赞(0)
    未经允许不得转载:171主机测评 » 登录注册模块
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址