如何在 Hugo 上实现私人加密页
文章目录
做了一些更新,现在把 private 单独放到一个路径下面,同时把私人也从 post 列表移除,从另一个地址进去。如此页面的观感就好多了。同时也对整个处理的过程进行了大幅修改,重写了原来的 script 脚本,并用 Deno 实现了主要逻辑。Shell 脚本主要是用来协调 Deno 脚本的运行的。
因为 AES 生成的结果不固定,导致 git 固定上传上去时,总会对这些文件进行修改,非常麻烦,于是我决定做了一个分离。将加密后的 md 文件上传,同时 ignore 未加密的文件。每次会生成一个 hash 值用来校验变动,如果变动,则进行文件同步。至于生成后的页面,简单加密一下就不管了,因为这里的变动本来就很杂。
这里就是一个缓存的思路,如果不做缓存的话,逻辑是根本做不出来的。同时,用 Shell 脚本写主逻辑实在是太累人了,用 Python ,用 Deno ,哪个都好,就是不要用 Shell 写。
之前我看过某位的博客,发现他的有些博文是前端加密处理的。简单来说,就是后端提前将页面加密好,由前端输入密码来进行解密,如果密码解开失败就会报错。缺点是显而易见的,加密算法基本是公开的,而且也不限制用户的解密次数,解开只是时间问题。但这个方法没有想象的那么糟,因为只要你对加密算法和密钥用点心,其实这个密文也不好破解。而且,对于静态博客页来说,成本低廉,便宜划算,这些密文也并非机密。
我垂涎这个功能挺久了。我的博客是采用 Hugo 生成的,但 Hugo 的源码并不支持这种操作。事实上,我也考虑过改 Hugo 源码,但这样需要改动 Hugo 的架构,最后还是放弃了。于是我尝试修改我原先的部署策略,并借助一套自动化的脚本来完成。
首先要制定整体流程
实际开发中其实还考虑到几个问题:
- 反复加密保证只加密一次。
- 反复解密保证只解密一次。
- 开发过程中保证博文处于解密状态。
- 最终上线状态需要能在本地查看。
因此最终流程与图中展示稍有不同。
最后实现其实不是尽善的,由于加密方法的问题,每次部署都会引起密文变动。对我而言,不好不坏吧,可以的话,还是希望能够固定密文。
对 Markdown 和主题的处理
首先,要将需要加密的 Markdown 头部设置 private: true
,同时放到 private
文件夹下。
接下来我们需要修改模板主题。主题需要考虑三点,第一是 summary
,内容不能外泄,第二是 rss ,第三是头部 meta 信息。设置
private: true
可以让我们直接用 .Params.private
来判断是否需要展示博文信息。我没有对字数、categories 和 tags
动手,主要是因为没有必要。
加密脚本
编写加密是整个工作的核心。一般你只要选个合适的算法,确保加密解密的正确性,其实也就到头了。
前端加密我使用 crypto-js ,但后端用什么呢?我尝试了一下 Python
,很难等效,但又不想用 Node ,于是用了 Deno 。现在新版的 Deno 可以使用
npm 的包了,我引用了 crypto-js
。为什么不用 Deno
自己的加密呢? Deno 自己实现的加密是 Web Crypto ,属于 low level
的加密原语,用起来十分难受。况且加密解密都用 crypto-js
主要是为了避坑。
Deno 还提供专门的 DOM 解析器,用来保持和浏览器行为一致,不过需要额外引用。操作起来还行。
加密 Markdown
加密 Markdown 需要通过头部的 private
判断该文件是否值得加密,这是其一。判断密文是否已经被加密过了,这是其二。
但我目前处理了第一点,第二点我是在流程上解决的。
加密 HTML
加密 HTML 与加密 Markdown 面临同样的问题,但 HTML 还算简单。
我们加密 HTML 的过程是这样的,首先提取中间的 body
部分,然后加密整个 body
的 HTML
,最后将密文作为注入的值传入到新的模板上。借助 DOMParser
,我们可以像在浏览器上一样操作 HTML 的 DOM
节点。同时,生成的新模板,我们可以向其中放置 Detect DOM ,只要探测到这个
DOM ,我们就跳过加密。实现上是容易的。
部署
部署分为预部署和正式部署。两者主要的加密解密流程是基本一致的,且与前面的流程图相差不多。
预部署需要在我本地运行,我个人选择了 php -S
来查看效果。而正式部署一直是用的 Web hooks
,这部分没有变,只不过我本地写在 hooks
里的脚本不能用了,全部使用我自己写的 blog
脚本函数处理。
结语
目前,这一顿操作下来,最大的快乐是顺带学习了一些加密算法。我昨天试了很久,由于 Python 和 crypto-js 在对字节的认识上不同,导致我踩了很多坑。同时我也试过了 Web Crypto ,这玩意儿还是有待成熟。不过,我最大的惊喜是 Deno ,它比以前成熟许多了,个人感觉 Deno 比 Node 适合 SSR 。 Node 现在也在逐渐与浏览器兼容,大前端是 Node 未来的方向。 winter 协议还在孵化,但我估计是未来的趋势了。
文章作者 bigshans
上次更新 2023-07-21