Astro 修改(4) -- 更快、更安全的 Waline 评论


关于 Waline

在我之前的 《大工程:从 Typecho 迁移到 Hexo》 一文中,已经简短的介绍过了 Waline 是什么,以及 Waline 为什么会成为我的选择。

简单来说:

  • Waline 增加了后端,相比于真·无后端的评论系统安全性高出一个通辽
  • 无需登录、注册即可评论
  • 从 Typecho 迁移起来还算方便

但 Waline 的默认配置也并非完全没有缺点,比如:

  • Waline 默认使用 libravatar 来提供头像,加载速度一言难尽…
  • 当评论者邮箱是 QQ 邮箱的时候,直接使用 QQ号 来加载头像,没有任何加密。在当下盒武器盛行的年代泄露 QQ 意味着什么自不必多说。
  • Waline 官方教程 中的数据库基于 LeanCloud,虽然免费,单次 DB 查询但更是慢到发指
  • 登录后才能评论会劝退很多人,但不登录就可以评论可能会被塞垃圾小广告

TLDR; 针对上述问题我都修改了什么?

  • 使用 Cravatar 替代默认的 libravatar,提升加载速度、增加安全性
  • 将基于 LeanCloud 的数据库迁移到白嫖的 MongoDB,大幅增加查询速度
  • 使用 Cloudflare 提供的 Turnstile 增加评论验证码,防止被广告塞满

各种公共头像服务

Gravatar

如果你经常在网上冲浪且接触过一些国外的服务的话,相信你肯定知道 Gravatar 是什么。

Gravatar 是一个全球通用的头像服务,用户只需要注册一个邮箱地址,之后在任何支持 Gravatar 的网站上都可以使用这个邮箱地址来获取头像。它是一个非常知名且被大部分网站所支持的公共头像服务,GitHub、Stack Overflow 等网站都在使用 Gravatar 服务。

但不管它有多少优点,一个缺点就足够毙掉它:大陆无法访问

Libravatar

LibravatarGravatar 在各种方面都非常类似,在大部分情况下,它们之间互相迁移只需要简单的改一下域名就可以。

Libravatar 各种方面都还不错,但它可以被 Cravatar 替代——不支持解析 QQ 邮箱对应的头像

WeAvatar

引用官网的介绍:

WeAvatar 首家支持手机号头像及字母默认头像,手机号头像更符合国内的使用习惯,字母头像可为没有头像的用户提供更好的体验。

再引用一段文档:

WeAvatar 头像 API 可以像普通的图片 URL 一样请求,具体格式是: https://weavatar.com/avatar/HASH

其中 HASH 部分是 邮箱 / 手机号 的 SHA256MD5哈希值,推荐使用 SHA256,此电子邮箱 / 手机号须在 weavatar.com 上添加头像,否则会尝试返回Gravatar 头像和 QQ 头像,如果都不存在,则返回默认头像

先不说个人博客索要手机号的必要性。在 2025 年的硬件算力下,跑出固定前缀、8 位可变纯数字的 MD5/SHA256 手机号彩虹表完全没有一点压力。参考:为100亿内的数字建立md5彩虹表的数据仓库

而泄露手机号的危害性基本等同于将你的身份证直接贴出来,所以这个东西在我个人看来就是 SB。

Cravatar

Cravatar 是中国认可的头像 (China Recognized Avatar) 的缩写。您只需上传一张图像并创建您的公共个人资料,然后当您参与任何支持 Cravatar 的网站时,您的 Cravatar 图像和公共个人资料将自动跟随您。

Cravatar 完全兼容 Gravatar,且大陆访问良好,此外还支持针对 QQ 邮箱的头像解析。

替换 Waline 的头像服务为 Cravatar

幸运的是,Waline 中访问 Libravatar 的邮件地址的 URL 就是 MD5 加密的,所以替换头像服务非常简单,根据 Waline 官方手册 环境变量部分,只需要修改服务器环境变量 GRAVATAR_STR 即可。

我的配置则是 https://cn.cravatar.com/avatar/{{mail|lower|trim|md5}}?s=150&d=retro

  • s=150 代表头像大小为 150px
  • d=retro 代表在无法获取头像时的默认头像

更多配置可以参考 Cravatar 的 API 文档

将 Waline 的数据库迁移到 MongoDB

根据 Waline 的 官方手册,Waline 支持 MongoDBMySQLPostgreSQLSQLiteTiDBCloudBaseLeanCloud 作为数据库。

刚好我注册过了 MongoDB 且整个 Blog 都在海外的服务器上,所以选择了 MongoDB 作为我的评论区数据库。

备份 LeanCloud 的数据库

在 Waline 的控制台中选择 导入导出,并导出数据库为 Json 即可。

创建 MongoDB

DataBase -> Clusters 点击 Create 后便可以创建一个数据库,在我这里,我选择了免费版本。

免费数据库拥有 512MB 的存储空间,对于只存放文本内容的评论区来说完全足够。

在 MongoDB 的控制台创建一个免费的数据库
在 MongoDB 的控制台创建一个免费的数据库

在选择完付费计划后,还需要修改额外选项。将 Region 选择到离你 Waline 后端 最近的地方,然后取消勾选 Preload sample dataset 即可。

我的 Waline 后端在 HK,所以这里数据库的区域也一并修改为 HK
我的 Waline 后端在 HK,所以这里数据库的区域也一并修改为 HK

创建用户权限组

在左侧找到 SECURITY -> Database Access,点击 Custom Roles -> ADD NEW CUSTOM ROLE

然后参考下图:

  1. 选一个你喜欢的名字
  2. 授予全部关于 Collections 的权限
  3. 指定数据库为 waline (如果你不知道你在干什么,最好不要乱改这里)
添加必要的读写权限
添加必要的读写权限

创建用户

在左侧点击 SECURITY -> Database Access,并继续点击 ADD NEW DATABASE USER

参考下图,各个选项的含义:

  1. 用户名 (记下它,我们后面还会用到)
  2. 密码 (记下它,我们后面还会用到)
  3. 授予自定义权限组
  4. 选择刚刚创建的权限组
  5. 限制这个用户可以连接到的资源
  6. 选择你创建好的数据库名 (一般来说这里只有一个,选择即可)
  7. 添加用户
创建新用户
创建新用户

获取、写入连接信息

在左侧点击 DATABASE -> Clusters,在页面上找到 Connect 并点击,便可以看到如下弹窗。

连接信息弹窗
连接信息弹窗

继续点击右下角的 View full instructions

在新弹出的窗口中,左侧选择 Drivers,右侧选择 Node.js、勾选 Get legacy (standard) connection string 即可看到如下图的链接信息。

详细连接信息
详细连接信息

我的链接信息如下:

MongoDB 链接信息
mongodb://test_user:<db_password>@
cdba.00-00.abcd.mongodb.net:27017, 
abcd.00-01.cdba.mongodb.net:27017,  
abcd.00-02.cdba.mongodb.net:27017/?
replicaSet=atlas-abcd-shard-0&
ssl=true&
authSource=admin&
retryWrites=true&
w=majority&
appName=BlogComments

上面高亮行将是我们需要的信息,结合上个步骤中的数据库账号密码,将所有信息整理一下:

MONGO_DB = waline  # MongoDB 数据库名称
MONGO_USER = test_user  # MongoDB 用户名
MONGO_PASSWORD = thepassword  # MongoDB 密码
MONGO_HOST = ["cdba.00-00.abcd.mongodb.net", "abcd.00-01.cdba.mongodb.net", "abcd.00-02.cdba.mongodb.net"]  # MongoDB 主机名
MONGO_PORT = [27017, 27017, 27017]  # MongoDB 端口号
MONGO_REPLICASET = atlas-abcd-shard-0  # MongoDB 集群
MONGO_AUTHSOURCE = admin  # MongoDB 认证源
MONGO_OPT_SSL = true  # 是否使用 SSL 进行连接

将其全部写入 Vercel 的环境变量中后,ReDeploy 一下即可。

恢复备份

非常简单,再次访问 Waline 的后台管理地址,选择 导入导出,然后选择 导入,将之前备份的 Json 文件上传即可。

增加 Cloudflare Turnstile 验证

创建 Turnstile 小组件

首先,直接去 Turnstile 的官网,点击 免费开始使用,然后选择 添加小组件

如下图,起一个好辨识的名字,并将你 博客的域名Waline 评论的域名 添加进去,交互级别、Cookies 绕过等高级功能可以自行查阅文档配置。

创建小组件
创建小组件

点击 创建 便可以拿到关键的两个秘钥:站点密钥密钥

服务端配置

站点秘钥写入 TURNSTILE_KEY 环境变量中,密钥写入 TURNSTILE_SECRET 环境变量中。

客户端配置

在客户端初始化 Waline 的时候,也需要一并将 Turnstile站点密钥传入。

我的 Waline 初始化代码
import { init } from '@waline/client/full';
import "@waline/client/style";
  
walineInstance = init({
    serverURL: "https://comments.blog.ixiaocai.net/",
    el: "#waline-comments-body",
    turnstileKey: "0x4AAAAAABABCDEFGH"
});

参考



评论加载中……