这篇文章记录一个静态博客里的文章可见性控制方案。目标是在没有数据库、没有登录系统、没有服务端鉴权的前提下,把文章分成公开、私密和需密码三种状态。
先说结论:静态站可以做“内容分发层面的可见性控制”,但不能做真正的权限系统。任何需要强安全的内容,都不应该只靠前端脚本保护。
三种状态
| 状态 | 说明 | 适用场景 |
|---|---|---|
| 公开 | 所有人可见 | 技术分享、项目复盘、教程 |
| 私密 | 只在源码中保留,不进入公开页面 | 个人笔记、草稿、未完成内容 |
| 需密码 | 有公开入口,但正文需要输入密码后查看 | 轻量内部分享、临时资料 |
这三个状态的核心区别,不是按钮样式,而是生成阶段如何处理文章。
Frontmatter 设计
公开文章可以不写 visibility,也可以显式声明:
---title: 文章可见性控制演示date: 2026-02-12 19:30:00tags: [Hexo, 教程]visibility: public---私密文章不应进入首页、归档、搜索和 sitemap:
---title: 我的私密日记date: 2026-02-12 20:00:00tags: [日记]visibility: private---需密码文章可以保留公开入口,但正文需要被保护:
---title: Vue3 高级教程会员版date: 2026-02-12 21:00:00tags: [Vue, 高级教程]visibility: passwordpasswordHash: "sha256-hash"---不要把明文密码写进公开生成产物。即使是 hash,也只能用于轻量门禁,不等于真正安全。
生成阶段过滤
静态站没有运行时数据库,所以最关键的控制点在构建阶段。
私密文章应该在生成列表时被过滤掉:
function isPublicPost(post) { return (post.visibility ?? "public") !== "private";}
const visiblePosts = allPosts.filter(isPublicPost);需要过滤的位置包括:
- 首页文章列表。
- 归档页。
- 标签页。
- 分类页。
- RSS。
- sitemap。
- 搜索索引。
只从首页隐藏是不够的。如果文章仍然进入 sitemap 或搜索索引,依然可能被发现。
密码门禁
前端密码门禁只能做轻量访问提示。示例结构:
<div class="password-gate" data-hash="hashed-password"> <input type="password" placeholder="请输入访问密码" /> <button type="button">查看文章</button></div>验证逻辑可以用 Web Crypto 计算 SHA-256:
async function verifyPassword(input, expectedHash) { const digest = await crypto.subtle.digest( "SHA-256", new TextEncoder().encode(input) );
const hash = [...new Uint8Array(digest)] .map(byte => byte.toString(16).padStart(2, "0")) .join("");
return hash === expectedHash;}但需要明确:如果正文已经被生成到 HTML,只是用 CSS 或 JS 隐藏,那就不安全。真正要提高保护程度,至少要在构建阶段把正文加密成密文,前端输入密码后再解密。
安全边界
静态博客的可见性控制适合:
- 草稿不进入公开列表。
- 内部资料做临时分享。
- 给读者一个访问提示。
- 轻量会员内容演示。
不适合:
- 保存真实敏感信息。
- 发布密钥、token、私钥。
- 保护商业机密。
- 做真正的用户权限系统。
真正需要权限控制的内容,应该放到有服务端鉴权的系统里,例如带登录、数据库、访问日志和权限校验的应用。
迁移到 Astro 后怎么做
Astro 的内容集合可以在 schema 层定义字段,例如:
visibility: z.enum(["public", "private", "password"]).default("public")然后在获取文章列表时统一过滤:
const posts = await getCollection("posts", post => { return post.data.visibility !== "private" && !post.data.draft;});这样比在模板里到处写判断更稳。生成 RSS、sitemap、搜索索引时也要复用同一套过滤逻辑。
复盘
这套方案的核心是区分“公开入口控制”和“内容安全保护”。静态博客可以很好地控制文章是否出现在列表、归档和索引里;但只要内容已经被生成到前端,任何人都有可能通过源码或网络请求看到。
所以,我更推荐把它作为内容管理能力,而不是安全能力。需要安全时,上服务端鉴权;需要写作管理时,用 frontmatter 控制生成结果。
COMMUNITY DISCUSSION
评论
使用 GitHub 账号登录后参与讨论,评论会同步到 GitHub Discussions。