惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

林间拾语

搜个微信客服被骗1900块,315曝光的“AI投毒”套路防不胜防 🌿 林间第5页拾语:OpenClaw 龙虾真的是刚需吗? 🌿 林间第4页拾语:再见 2025 Halo 2.22.x 插件集成 Redis 完整指南 告别等待!Halo在线客服插件,让网站沟通秒回时代 🌿 林间第3页拾语:把事情做好,把自己照顾好 从 0 到熟练:Mermaid 流程图的进阶之路 智阅AI助手第四次重构上线:这次把“摘要”两个字删掉了 禅导航 v2 升级:彻底重构,只为更好用 谈谈SEO:什么是SEO,如何做好SEO,及需要注意的事项 🌿 林间第2页拾语:糟心事很少,懂你的人刚好够 智阅 GPT V3 版本:全面升级,让内容精髓触手可及 全面了解腾讯 EdgeOne 边缘加速:加速网站并提高用户体验 数字隐私与数据安全:推销电话背后的隐私泄露风险 两个小插件偷偷上线了:SEO 时间因子 & 公告弹窗 MacOS 和 Linux 使用 SDKMAN 管理 Java 工具链 🌿 林间第1页拾语:光没来前,咱先煮点饭吧 Halo插件|一个面向创作者的多功能AI媒体处理工具集 林间拾语|一次命名的回归,也是一种自我表达
Halo 2.21.x 登录弹窗:从后端机制到前端实现
Handsome · 2025-12-08 · via 林间拾语

|

整体登录流程概览

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

效果视频: