1Panel 部署 FastAdmin 管理端访问 302 解决方案
最近使用 1Panel 面板部署 FastAdmin 项目用于测试,站点的伪静态选择 thinkphp,在部署完成后发现用户端可以正常访问,而管理端则会无限制重定向到 login/index,最终提示 “重定向次数过多...” 如下图所示:

经过排查 发现问题出现在 1Panel 自带的 fastcgi-php.conf 上这个文件上,如图 21 行:

解决方案是注释掉这一行,然后使用 fastadmin 官方推荐的 fastcgi 配置,代码如下:
location ~ [^/]\.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
# include fastcgi-php.conf; # 注释掉这一行或者直接复制我的示例代码
include fastcgi_params;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}保存修改的配置后,fastadmin 管理端入口即可正常访问:

使用版本为 1Panel 2.0.16, OpenResty 版本为 1.27.1.2-2-3-focal
离线授权码设计思路
本文系统性地探讨了软件产品的离线授权码设计思路与实现方案。文章首先区分了软件层面与硬件层面的授权方式,并聚焦于更灵活、低成本的软件授权码机制。设计核心在于授权码需具备设备绑定性、安全性、可验证性、可复现性等特征。实现的关键步骤包括获取设备的唯一稳定标识(如CPUID、主板UUID等),并在此基础上构建授权码。 文章详细剖析了两种主流技术方案:对称加密方案与非对称加密方案。对称方案通过将机器码、项目名、有效期与盐值拼接后进行哈希(如MD5)生成签名,并采用36进制编码等技巧优化用户体验,使其便于手动输入,但密钥需内置于客户端,存在一定逆向风险。非对称方案基于RSA算法,可签发包含丰富授权信息(如功能模块、有效期)的JSON格式许可证,安全性更高但授权数据较长。此外,文中也简要介绍了基于标准JWT的实现途径。 最后,文章指出了离线授权的安全局限性,并针对“时钟回拨”这一常见破解手段,提出了记录安全时间戳、与业务数据关联等实用的缓解措施。整体而言,文章提供了从基础设计到具体实现的多维度技术参考。
SQLite + zstd:定时任务日志压缩优化实践
针对定时任务日志系统的性能与存储压力问题,我们重构了原有基于MySQL的Webcron系统。原系统因日志查询与主业务共用数据库,导致页面加载严重超时;同时高频任务产生的海量日志数据急剧膨胀,占用大量磁盘空间。为此,我们采用SQLite替代MySQL作为独立的日志存储引擎,以消除对主业务的影响。核心优化在于应用zstd压缩算法,针对大于150字节的日志内容进行压缩,相比明文存储和gzip,实现了更优的压缩比与性能平衡。我们设计了按月分库的存储策略,将每月日志存入独立的SQLite文件,既简化了数据清理,也保证了查询性能的稳定。最终方案使用Go语言结合GORM与zstd库实现,达到每10万条日志仅占约10MB的压缩效果,并在数百万条日志中实现了毫秒级查询。此实践证明,对于中小型系统,SQLite配合压缩技术是一种轻量、高效且易于维护的日志管理方案。未来可探索DuckDB及动态字典等方向进一步优化。
解析到本地127的神奇域名
本文探讨了 Web 本地开发中,除 `127.0.0.1` 与 `localhost` 外,可专门解析到本地回环地址的实用域名及其应用场景。作者梳理了多个稳定可用的选项:**localhost** 及其子域名作为 IETF 官方规范,通用性最强;**lvh.me** 因其极短长度和泛域名支持,成为日常开发优选;**nip.io** 及其 **local.gd** 服务则提供了基于 IP 生成域名的灵活方案;此外还有如 **fbi.com** 等趣闻域名。这些本地域名主要解决了使用纯 IP 地址开发时面临的局限:它们能更好地模拟真实环境,支持 **Cookie 的子域名共享**;满足 OAuth 等服务商要求必须使用域名作为回调地址的强制规定;在同时开发多项目或多租户系统时,能通过清晰的子域名(如 `project-a.lvh.me`)进行区分,避免端口号混乱;同时也有助于构建与生产环境一致的多模块(如 admin、api)访问结构,实现代码逻辑的无缝迁移。
Typecho 多用户二次认证插件
该插件为Typecho 1.2.0+版本提供基于OTP的多用户二次认证功能。作者因现有扩展不支持多用户而开发此方案,插件具有界面简洁、支持多用户的特点。核心功能是在登录页面集成动态码输入框,实现账户密码与OTP验证码的双重校验。 用户需在个人设置页面扫描二维码或手动绑定OTP密钥,绑定后密钥固定,未绑定时页面会随机生成密钥。插件允许用户验证并解绑已有OTP认证。登录时,已绑定用户必须输入正确动态码,未绑定用户则可直接登录。安装时需将文件夹上传至插件目录并启用。 配置选项包括时间窗口期设置(用于处理时间戳差异)和防呆设计(需确认卸载以防止误操作导致密钥丢失)。更新记录显示插件已修复PHP 8.2语法不兼容及表单错误挂载问题。
利用短信模板提取短信变量
本文针对业务系统需兼容不同短信平台(部分要求传递模板变量,部分要求传递原文)的需求,提出一种基于正则表达式自动从短信原文中提取模板变量的解决方案。核心思路分为三步:首先,利用正则匹配模板中的变量标签(如 `${...}`),提取出所有变量名组成键数组;其次,将模板中的变量标签部分替换为通用正则捕获组 `(.*)`,形成一个用于匹配短信原文的正则表达式,并提取出对应值数组;最后,将键数组与值数组组合,生成平台所需的参数格式。文章以一个包含多个变量的复杂短信为例,详细展示了PHP实现过程,并指出使用该方法时需注意变量标签需转义正则字符、模板变量不可连续或嵌套等约束条件,为多平台短信发送场景提供了一种灵活的适配思路。
Gin + go:embed 实现静态资源嵌入
本文介绍了如何利用 Go 1.16 引入的 `go:embed` 特性,将前端静态资源文件在编译时嵌入 Go 程序,从而构建单文件部署的 Web 服务。通过声明 `//go:embed` 指令,可将指定目录或文件打包为 `embed.FS` 虚拟文件系统。结合 Gin 框架,开发者可以使用 `http.FS()` 包装该文件系统,并通过 `StaticFS` 或 `NoRoute` 方法将其作为静态资源提供。特别是利用 `NoRoute` 回调,可以在未匹配到 API 路由时自动将请求转发至静态文件服务器,从而省略路径前缀,实现 API 接口与静态资源的统一部署。这种方式简化了发布流程,并避免了跨域问题。
go:embed 嵌入 HTTPS 证书
这是一篇关于使用Go语言`go:embed`功能将HTTPS证书嵌入可执行文件的技术教程。文章首先阐述了为Web服务启用HTTPS的必要性,即使在内网环境中,以保障数据传输安全、完整性并规避浏览器限制。针对内网无域名的场景,文章重点介绍了使用`openssl`生成自签名证书的具体步骤。核心部分详细演示了如何利用`go:embed`指令在编译时将证书文件(`.crt`与`.key`或合并后的`.pem`)嵌入程序变量,并解决Gin框架无法直接加载嵌入式证书的问题。通过自定义`http.Server`的`TLSConfig`配置,成功加载字节形式的证书,最终实现了将静态资源与HTTPS证书一并打包、开箱即用的Gin HTTPS服务。教程明确了`RunTLS`方法不适用于此场景,并展示了最终效果。
Go Server HTTP 302 跳转 HTTPS
这篇笔记从Go服务器部署HTTPS后的实际问题切入,作者遇到了HTTP 400错误——当用户直接输入IP地址访问时,浏览器自动补充HTTP协议,与HTTPS服务冲突,导致服务器返回“Client sent an HTTP request to an HTTPS server”。根因在于Go官方没有内置HTTP到HTTPS的重定向功能,而手动修改协议方式不够便捷。 作者最初尝试在Gin中间件中检测TLS报文,但发现多次请求后识别不可靠。后来发现开源库 `hlfhr`,它通过劫持 `net.Conn` 实现自动重定向。具体方案是加载证书后,用 `hlfhr.New` 创建服务器并监听端口,实现访问HTTP时自动302跳转HTTPS。作者还fork项目调整状态码为307,避免POST请求被误转为GET,提升兼容性。 效果上,改造后用户访问HTTP地址会自动跳转至HTTPS,解决了体验痛点。对于Go开发者,这提供了一个轻量级的实现思路。