技术文档

给私人板块加访问口令

纯静态站点没有后端,拦截只能做在页面这一层。这篇记录现在的做法: URL 带一个 ?token= 参数,口令对了正文才显示——不用碰服务器配置,clone 下来就是能跑的成品。

怎么进

两种方式,效果一样:

  • 在网址后面加参数:/private/?token=moyu2026
  • 打开 /private/,在口令框里输入

口令对了就记进浏览器的 localStorage,之后直接进,不用重复输入。 页面上有个「锁定」按钮,清掉这个记录,下一次访问又要口令。

走 URL 参数进来时,脚本会用 history.replaceState 把 ?token= 从地址栏里抹掉—— 口令不该留在浏览器历史和 referer 里。

口令在哪改

只有一处,脚本的第一行:

// private/private-auth.js
var TOKEN = "moyu2026";  // ← 口令

改完 push 上去就换口令了,不用动服务器。旧的解锁记录会自动失效—— 脚本会核对记在 localStorage 里的口令和当前口令是不是一致。

解锁记录能存多久

TTL_DAYS = 30。超过三十天就算过期,下次访问要重新输。 想更短就改小这个数,想永久有效就把它设成一个很大的值。

为什么正文默认是藏着的

<html> 上默认带着 class="is-locked",CSS 据此把正文藏起来、显示口令页。 脚本在 <head> 里同步跑完,确认可以进就换成 is-unlocked。 所以解锁的时候正文是直接出现的,不会先闪一下再消失。

这个脚本是普通脚本而不是 type="module":module 是 defer 的, 要等 HTML 解析完才执行,那样正文会先露出来再被藏回去。

万一脚本没跑起来(被拦截、报错),class="is-locked" 还在,正文仍然是藏着的—— 失败时是打不开,不是打开的。

这层拦截挡得住什么

说清楚比说得强重要:

  • 挡得住:随手点进 /private/ 的人、搜索引擎(页面带 noindex,robots.txt 里也挡了)、以及把链接分享到群里的场景;
  • 挡不住:专门来读的人。口令写在公开的 private/private-auth.js 里,内容也仍是仓库里的明文, 直接 curl 那个 .html 文件,照样能拿到全文。
这是「不外传」而不是「不泄露」。真正的拦截要放在服务器上——比如 nginx 的 auth_basic, 请求在到达文件之前就被挡下,文件根本不会离开服务器。

如果哪天觉得不够

换成服务器层拦截,只要在宝塔的站点配置里加一段 location,页面这边的代码可以原样留着 (多一层总比少一层好):

location ^~ /private/ {
    auth_basic "私人板块";
    auth_basic_user_file /www/wwwroot/all-in-one/.htpasswd;
    index index.html;
}

凭据文件用 openssl passwd -6 生成:

printf 'liuyu:%s\n' "$(openssl passwd -6 -salt "$(openssl rand -hex 6)" '你的口令')" > /www/wwwroot/all-in-one/.htpasswd

记得给 .htpasswd 和 .git 各加一条 deny all—— 站点根目录就是仓库目录,不挡的话 /.git/config 会把远端地址和整个提交历史交出去。

← 回到技术文档