# 引言
终于又重启博客了,平时开发折腾过程中遇到的一些问题,感觉不错的会发布到博客中。
但是有些文章如果存在隐私内容,或者不打算公开的话,就不能放在博客中了,但是一些文章挂在网页上又可以方便自己查看,于是折腾了下 Hexo
的文章加密
# 调研
以前用 wordpress
的时候,也折腾过类似的需求,由于是 动态网站,所以其实还是比较方便的,这一次使用了Hexo
这个 静态博客 框架,说实话我都怀疑有没有可行的方案🤣🤣🤣
不过好在还是找到了一个 Hexo
插件 hexo-blog-encrypt
能够实现文章加密的需求
# 插件安装
使用如下命令安装
npm install hexo-blog-encrypt --save |
该插件的使用也很方便,使用时只需要在文章的 Front-matter
添加 password
即可。
--- | |
title: Hello World | |
date: 2022-05-13 21:18:02 | |
password: 12345 | |
--- |
下面展开讲一些比较实用的设置,更详细的可以查看官方文档。 D0n9X1n/hexo-blog-encrypt: Yet, just another hexo plugin for security.
# 全局加密配置
分别为每篇文章设置密码,虽然很灵活,但是配置或者修改起来非常麻烦。
好在,我们可以针对 tag
做全局统一配置,这样需要进行加密的文章,只需要引入指定的 tag
分类即可
Hexo
主配置文件_config.yml
中新增全局配置
# Security - hexo-blog-encrypt | |
encrypt: | |
silent: true | |
theme: xray | |
abstract: 这是一篇加密文章,需要密码才能继续阅读。 | |
message: 当前文章暂不对外可见,请输入密码后查看! | |
tags: | |
- {name: private, password: hello} | |
wrong_pass_message: 抱歉,您输入的密码错误,请检查后重新输入。 |
其中的 tag
部分可以定义多个,不同加密系列,采取不同的密码
- 文章头部
Front-matter
引入加密的tag
--- | |
title: Password Test | |
date: 2022-05-03 21:28:03 | |
tags: | |
- private | |
--- |
这样文章就被加密了,密码就是 private
标签对应的密码
- 全局加密豁免
可能有这样的情况,属于 private
标签下的某篇文章可能需要公开,不可能说把密码直接在描述信息中公开吧。
好在插件配置 优先级 为 文章Front-matter
> _config.yml配置
> 默认配置
这时候,可以在 Front-matter
中对加密设置进行覆盖,只需要在使用 加密tag
的前提下,结合 password
来实现即可。在博客文章的头部添加 password
并设置为 ""
就能取消当前文章的加密
--- | |
title: Password Test | |
date: 2022-05-03 21:28:03 | |
tags: | |
- private | |
password: "" | |
--- |
- 全局加密设置非全局密码
可能有如下场景,属于 private
标签下的某篇文章想要设置成不一样的密码。
还是利用配置的优先级在 Front-matter
中对加密设置进行覆盖即可,在博客文章的头部添加 password
并设置为 自定义密码 就可以使用 自定义密码 加密当前文章了
--- | |
title: Password Test | |
date: 2022-05-03 21:28:03 | |
tags: | |
- private | |
password: "special" | |
--- |
# Shoka 主题适配
# 解密后目录不显示
为文章设置了 加密 后查看 之后,不经意间发现这些文章的目录在解密后却不显示了。
在插件的 github issues
中有相关问题的讨论 解密后目录不会更新・Issue #16
主要原因就是加密的时候, post.content
会变成加密后的串,所以原来的 TOC
生成逻辑就会针对加密后的内容。
所以这边我只能把原来的内容存进 post.origin
字段。
Shoka 主题的针对修改如下:
- 主题文件
themes/shoka/layout/_macro/sidebar.njk
找到 [宏]{.blue}render
,修改目录生成部分如下
<div class="inner"> | |
<!--modify begin--> | |
{%- if display_toc %} | |
{%- if (page.encrypt) %} | |
{%- set toc = toc(page.origin) %} | |
{%- else %} | |
{%- set toc = toc(page.content) %} | |
{%- endif %} | |
{%- set display_toc = toc.length > 1 and display_toc %} | |
{%- set related = _category_posts(page) %} | |
{%- endif %} | |
<!--modify end--> | |
<!--others--> | |
</div> |
- 还是主题文件
themes/shoka/layout/_macro/sidebar.njk
替换 <div class="panels">...</div>
如下
<div class="panels"> | |
<div class="inner"> | |
<div class="contents panel pjax" data-title="{{ __('sidebar.toc') }}"> | |
{%- if (page.encrypt) %} | |
<div id="toc-div" style="display:none"> | |
{%- if display_toc %} | |
{{ toc }} | |
{%- endif %} | |
</div> | |
{%- else %} | |
{%- if display_toc %} | |
{{ toc }} | |
{%- endif %} | |
{%- endif %} | |
</div> | |
<div class="related panel pjax" data-title="{{ __('sidebar.related') }}"> | |
{%- if related %} | |
<ul> | |
{{ related }} | |
</ul> | |
{%- endif %} | |
</div> | |
<div class="overview panel" data-title="{{ __('sidebar.overview') }}"> | |
{{ partial('_partials/sidebar/overview.njk', {}, {cache: true}) }} | |
</div> | |
</div> | |
</div> |
主要缘由是现在加密后的文章未解密之前也可以看到 文章目录,虽然该目录不可点击,但是这很不 优雅
理想中的效果应该是:
- 当文章加密后,访客只能看到侧边栏中的
站点概览
部分,不需要看到文章目录
部分。 - 当文章解密后,访客则可以看到
站点概览
和文章目录
两部分。
查看了 hexo-blog-encrypt
相关的 issues
Archer 主题解密后 TOC 依旧不显示(已按手册修改)・Issue #67, 最总找到了一种 折中 的解决方法
这种方法并不是完全的加密,而是采用 障眼法 的方式,通过查看 html 源文件还是可以看到目录内容的,只是不显示罢了。
对于这个问题, hexo-blog-encrypt
插件的作者也作了说明: next 主题内没有 article.ejs 文件【TOC 相关】・Issue #162・D0n9X1n/hexo-blog-encrypt,暂时只能妥协。
前后效果对比如下,解锁前隐藏目录,解锁后再显示目录,但是目录区域一直存在
# 文章元数据显示加密图标
- 主题语言包
themes/shoka/languages/zh-CN.yml
下post
新增加密显示文字
post: | |
encrypt: 『加密』 |
下一步骤引用的 post.encrypt
就是这里的配置
- 主题文件
themes/shoka/layout/_macro/postmeta.njk
, 找到 [宏]{.blue}render
在 {%- set create_title = __('post.created') + __('symbol.colon') + full_date(item.date)
} 上修改代码如下
{% macro render(item, full = false) %} | |
<div class="meta"> | |
<!--modify begin--> | |
{%- if item.encrypt %} | |
<span class="item" title="{{ __('post.encrypt') }}" style="margin-right: -0.625rem"> | |
<span class="icon"> | |
<i class="ic i-compress"></i> | |
</span> | |
<span class="encrypt"> | |
<font>{{ __('post.encrypt') }}</font> | |
</span> | |
</span> | |
{%- endif %} | |
<!--modify end--> | |
{%- set create_title = __('post.created') + __('symbol.colon') + full_date(item.date) %} | |
<!--others--> | |
</div> | |
{% endmacro %} |
- 主题样式
themes/shoka/source/css/_common/components/post/post.styl
新增样式
span.encrypt { | |
white-space: pre; | |
the-transition(); | |
font { | |
color: #d96e80 | |
} | |
span { | |
white-space: normal; | |
} | |
a { | |
color: var(--primary-color); | |
} | |
margin-left: -0.415rem | |
} |
最终效果如下,同样的效果在首页文章的预览标签也会出现~
# 结语
Hexo
三连完结撒花~~