Halo 2.21.x 登录弹窗:从后端机制到前端实现

Handsome
2025-12-08
点 赞
3
热 度
331
评 论
3
  1. 首页
  2. 林间·栈笔
  3. Halo 2.21.x 登录弹窗:从后端机制到前端实现

整体登录流程概览

1.1 后端组件总览

PreAuthLoginEndpoint 预登录端点:

  • 处理 GET /login 请求。

  • 调用 CryptoService.readPublicKey() 读取 RSA 公钥。

  • 调用 AuthProviderService 查询启用的登录方式(本地表单、社交登录等)。

  • 获取全局站点信息,最后渲染 Thymeleaf 模板(登录页 HTML)。

  • 对前端的意义

  • /login 页面是我们能看到的唯一“官方视角”,公钥、CSRF、登录方式等信息都在这里以 HTML/JS 的形式暴露出来。

CryptoService(接口) / RsaKeyService(实现)

  • 管理 RSA 公私钥对。

  • readPublicKey():给 PreAuthLoginEndpoint 用,把公钥塞到前端页面。

  • decrypt(byte[]):给登录链路用,解密前端传来的密文密码。

对前端的意义

如果站点启用了“前端加密 + 后端解密”的模式,我们必须用与后端一致的公钥和算法才能登录成功。

AuthProviderService

  • 负责登录方式(本地用户名密码、第三方 OAuth 等)的查询与过滤。

  • 结果在 /login 页面中以按钮、链接的形式体现。

LoginSecurityConfigurer + AuthenticationWebFilter

  • 在 Spring Security 过滤器链中注册表单登录过滤器 AuthenticationWebFilter

  • 统一处理 POST /login 请求,进入认证流程。

  • 对前端的意义

  • 不管是原始表单提交,还是我们自定义的 fetch('/login'),最终都会走到这个过滤器链上。

LoginAuthenticationConverter

  • 从请求(表单或 JSON)中读取:

  • username

  • password(明文或密文);

  • _csrf 等字段。

  • 如果启用了前端加密:

  • 先调用 CryptoService.decrypt() 把密文解密成明文密码;

  • 然后把用户名和明文密码交给认证管理器。

对前端的意义

决定了“密码字段到底是明文还是密文”这件事怎么处理——只要我们按照它接受的格式提交,就不需要改任何后端代码。

DefaultUserDetailService / UserService / RoleService

  • 加载用户信息和角色列表;

  • 封装为 HaloUserDetails,支持标记是否启用 2FA。

  • 对前端的意义

  • 走到这一步,说明我们的请求已经成功通过了表单解析与密码解密这一关。

UsernamePasswordHandler

  • 处理登录成功或失败;

  • 可以选择:

  • 返回 JSON;

  • 或者重定向到某个页面;

  • 配合 RememberMeRequestCache 等组件做“记住我”之类的增强。

  • 对前端的意义

  • 决定了我们的 fetch('/login') 最终会得到 JSON 还是重定向,直接影响弹窗里怎么展示结果。

    1.2 模块关系图

flowchart TD B[Browser 前端] -->|GET /login 登录页| P[PreAuthLoginEndpoint 预登录端点] B -->|POST /login 提交表单或 fetch| F[AuthenticationWebFilter 表单登录过滤器] P --> C[CryptoService / RsaKeyService] P --> APS[AuthProviderService 登录方式服务] P --> GI[GlobalInfoService 全局站点信息] P --> T[Thymeleaf 模板 login.html] F --> LAC[LoginAuthenticationConverter 表单转换器] LAC --> C F --> AM[ReactiveAuthenticationManager 认证管理器] AM --> UDS[DefaultUserDetailService 用户明细服务] UDS --> USvc[UserService 用户查询] UDS --> RSvc[RoleService 角色查询] F --> H[UsernamePasswordHandler 成功/失败处理器] H --> RM[RememberMeRequestCache 记住我]

1.3 总结

/login 页面:

  1. 不只是一个普通 HTML,而是后端"打包好的登录环境快照";

  2. 里面**可能**包含publicKey 变量_csrf、可选的社交登录按钮等。

POST /login

  1. 不关心请求是从弹窗还是原生页面发出的;

  2. 只关心字段名和格式是否符合 LoginAuthenticationConverter 的预期;

  3. 密码既可以是明文(由后端直接校验),也可以是密文(由后端用私钥解密)。

这意味着:

只要我们在前端构造出一份“看起来像 /login 表单提交”的请求,就可以无侵入地接入整条登录链路。

提供一个截图:

我已经实现了 弹窗登录功能 有需要的可以找我要,暂时不打算全部公开不知道会不会有什么BUG
效果视频:


心若有所向往,何惧道阻且长

Handsome

infp 调停者

站长

不具版权性
不具时效性

文章内容不具时效性。若文章内容有错误之处,请您批评指正。

切换评论

目录

欢迎来到Handsome的站点,为您导航全站动态

44 文章数
4 分类数
186 评论数
46标签数