Zeee 文 6111 kHz 3,968 字

大家好,这里是明知即使把Velas Weekly改成Velas Annual也很离谱毕竟已经整整三年没更新这个系列但最后还是没有把标题写成Velas Annual Issue 1因为怕你们以为我开了新坑的Zeee。能一口气读完这句话也是很厉害

突然诈尸是因为好不容易攒够了能发一次Velas Weekly的更新。不过在这之前先让我想想有哪些改进是上次没写的,权当是这三年来电波站更新的“总集篇”吧。

最小化互动信息显示(2020年)

发现没有存什么改版前的电波站的截图,勉强只在上一篇Velas Weekly里找到了这张。

改版前的电波站
改版前的电波站

原来三年前的Safari长这样。

由于没有像一些博客那样将最新的评论列出来,那时的电波站采用了这种把点赞与评论数显示在文章卡片上的设计(其实在早些时候还会显示阅读数)。初衷大概有几点:

  1. 让访客能在首页上直观地看见自己与他人的互动给电波站留下的“痕迹”,以此来增加大家的参与感和互动意愿;
  2. 社交平台也是这样设计的,它可以间接帮访客甄别文章的价值;
  3. 某种程度上,作为一名创作者,这些互动数也是一种给我自己的激励。

但渐渐的,我却被这些“数字”给绕进去了。

发现自己变得患得患失:在被增长的数字鼓励之余,会为一篇我自满的文章的数据没有其他文章“好看”而沮丧。也会对身边人出于好心的“给文章刷赞”的行为感到不悦,认为这种“不公正”的行为在打破某种微妙的平衡。

但仔细想,这些“数字”真的可以量化一篇文章的“价值”吗?

如果是,要多少个“赞”的文章才能算得上是一篇“好”文章呢?

对于“曝光率”低的“旧文章”,或是对那些留存率高但少人点赞的文章来说,他们就是“不好”的文章了么?

但这里不是我的个人网站么,我为什么要在意这些数据?

后来读到了Jesse老师写的《社交围城里的刷新机器》,才意识到这套即时激励机制所产生的诸多负面影响。而我上述所提到的困扰,也是这种影响的写照。

于是在2020年底我精简了电波站的设计,其中一项便是仅在文章最底部的互动区域显示点赞与评论数,在网站的其余位置(包括在后台)都一律不展示。

削弱了“数字”的反馈之后,互动数确实比以前下降了许多,更新的动力也相对没有那么足了。但于此,我也开始静下心来,去思考对于电波站来说什么才是更重要的、什么才是更值得关注的。毕竟比起一个个“数字”,那颗“为自己而创作”的心才是我建立这个博客的初衷。

至于为何最终没有彻底移除点赞和评论功能,大概还是渴望能听到一丝来自读者的回应吧——除了“记录”,“创作”是电波站的另一个重要属性,而创作者永远是孤独的。

曾经想要“有深度的交流”的我,试过彻底将点赞功能从电波站隐去了一阵子。但由于留言的人实在太少了(尤其是对小说这类很难引起共鸣的文章),直接把我整自闭了。(所以能在没有互动的情况下坚持更新的博主真的很厉害。) 或许比起一下子从一极走到另一极,寻找两者之间的平衡点才更为重要。

偶然间看到了A酱的VOID的互动时间线设计,我大受启发:这也许是自己想要的那个平衡点呢?「一到Weekly就cue A酱(1/1)」成就Get

VOID的时间线功能
VOID的时间线功能

于是也给电波站的后台整了一个类似的。(截图已隐去IP/归属地、UA等网络特征信息。考虑到第一次展示电波站后台,可能会引起部分人士的疑虑,若有相关疑问,请参照常见问题六:电波站会采集我的个人信息吗?

Lynx的时间线功能
每次点赞/评论后,我看到的样子

比起冷冰冰的数字,这样更富有“人”的气息,而且看到这样的信息真的很受鼓舞。

不过相信我,即便对于常客,我也没办法从UA(User Agent)和IP归属地猜到是谁点的赞,只知道这是来自地球某个角落 (又或者是谁的VPN) 的祝福。所以可能的话,还是通过留言来告诉我你的想法吧,我会很乐意写回复的。

不知不觉写了很多,引用《社交围城里的刷新机器》最后一段话作为本节结语:

发完这篇博客,我应该还是会坐在电脑前,打开 Google Analytics,按几下「刷新」,看看又有几个人正在读。但这件事不会持续太久,因为我知道,社交媒体的围城之外,还有一个更大的世界。

设计与交互微调(2021-2022年)

字体切换

Velas Weekly Issue 8中提到,Velas电波站导航栏重构的直接原因就是为了点赞方便 (对不起,我就是个贪恋多巴胺的人类)。如今点赞按钮从导航栏上拿掉了,顿时觉得有点空空的。

这时,我想到@ZGGSONG在留言板的提议,于是把“衬线体/无衬线体”切换的功能提上了日程。

字体切换
取代了点赞的“字体切换”按钮

功能的实现细节没什么好说的,估计和其他博客主题的方法差不多。

不过有个设计上的小插曲想借此分享一下。

在最初实现的时候,电波站就将衬线体(“思源宋体”)默认引入了。衬线体按钮旁边的效果预览(“字”)就是单独使用“思源宋体”所渲染(考虑到有访客不了解两个选项的区别)。但发现它会影响网站的整体载入时间,于是又转为“只有当点击该选项时才将其引入”的“懒加载”策略。

但是问题又来了,由于没有默认加载“思源宋体”,这时“衬线体”选项旁的效果预览就失效了。

我沉思了半晌,突然灵机一动:打开PS,用文本框写了个“字”,设成思源宋体,导出成SVG格式,作为图片导入网站前端——问题解决啦!如今即便没有加载字体包,依旧能渲染“思源宋体”的“字”。(而且还支持夜间模式)

没错,Velas电波站就是由无数个像这样意义不明的细节堆起来的。

数据缓存

由于文章列表不再需要展示文章的互动数这类即时信息,这也让缓存文章列表成为了可能。(当然,以前也能做缓存。只是每次数据变化都要清理缓存,故效果相对不明显。)

于是引入了lru-cache这个包,使用LRU(“最近最少使用”算法)对各个类别下的文章列表进行了缓存。现在只有在文章发表/修改时,后端才会清理这部分的缓存,最直观的影响就是减少了对数据库的读取,加快了页面的载入速度。

此外,一并加入缓存机制的还有轮播图、各页面的相关文章等不常更新的数据。

这样看来,隐去互动数还有不少技术上的好处。

画廊

一直很馋TyplogVOID那种多图排版(效果可参考Just lepture的这篇博客),很有看杂志的感觉。

但又因为电波站文章的图片注解用得比较多,而上述的这种排版方式对(不遮挡图片的)注解支持不友好,我想寻找另一种更适合电波站风格的解决方式。(说了那么多,其实就是不想再搬VOID的设计了。)

于是,“画廊”诞生了。

画廊
画廊

这种图片浏览的交互在很多地方已经用过了。我之所以采用这种解决方案,除了它对注解支持良好外,还因为它即使放入再多的图片,也不会增加正文的长度 (别管RSS了)。这个特性很适合插入一些作为补充正文用的图片。

但由于它需要交互才能浏览图片的局限性,在两张图片并排显示的场合,我还是采用了与Typlog的类似解决方案。真香

后台双因素登录(2023年)

终于写到这了,这Recap好长啊哈哈。明明写这篇Weekly只是由于这周我给电波站后台加入的双因素认证功能,却为了一碟醋包了盘饺子。

双因素认证

起因是我每次翻服务器的日志,总会看到某些不明生物的恶意访问(撞库)记录。在将其IP拉黑之余,不由得为小站能在网络洪流中存活至今捏一把汗。动态博客系统真是麻烦。

防患于未然,于是给后台加上了双因素认证。

我使用的是node-2fa这个包的实现。它用TOTP(Time-based One-time Password,“基于时间的一次性密码”)的方法生成动态令牌,具体的介绍和算法可以参考这篇文章

大体上的判断逻辑其实挺简单的 (毕竟复杂的是算法,模块作者都替我做了),只需要写一个生成初始化二维码的请求,将初始化的密钥存入数据库,并在登录的时候加一个与数据库中的密钥比对的TOTP校验就好(对数据库中没密钥的用户则跳过校验)。

难倒我的地方是:

一般来说,双因素认证流程走的是“输入账号密码”➡️“点击登录”➡️“输入双因素认证码”➡️“点击确认”

但由于电波站服务端的身份验证是用OAuth2.0实现的,我不知服务端如何在“输入双因素认证码”阶段依旧能知晓该用户在上一阶段输入了正确的账号密码。毕竟在REST的两步认证中,用户的身份Token只有在双因素认证码输入正确之后才会生成。那前一个阶段,即在“输入了正确的账号密码”之后,服务端又该如何标识此用户呢?

查了一些文章文档,发现他们的REST API设计都在登录请求中同时接收用户的账号、密码和双因素认证码三个输入。

故做了一个不负责任的猜想:可能对于REST来说,在第一次“输入账号密码”阶段,服务端主要是在判断该用户是否开启了双因素认证,从而判断到底是应该直接生成Token并放其通行(没开启双因素),还是应该跳转到两步认证阶段(开启了双因素)。而到了“输入双因素认证码”阶段,客户端又把用户之前输入的账号密码、连同新输入的认证码向服务端发送一遍,这又进行了一次登录认证(生成Token)。

希望有经验的小伙伴可以解答一下。

但不管怎么样,这种(设想中的)流程虽然有点冗余,但起码安全性是足够的。而且对于电波站这个只有一个管理员账号的系统来说,我甚至可以在打开登录界面之前,判断数据库中唯一的用户是否设置了双因素认证就好。

于是,终于能放心把OAuth的Token有效期延长了。即便多了一个认证步骤,实质上我也不需要频繁走这个登录流程,总体而言还是省事的。

登录界面
不觉得这个动效……很好看么?

很不爽的是弄了那么多,这个界面最终只有我能看到。(什么?你说上面的截图暴露了Lynx的网址?才……才不是故意的)

WebAuthn

直到把双因素认证做好,我才了解到世上原来还有个更先进的Web身份认证方式:WebAuthn

它可以让你的Web App直接调用设备自带的生物识别传感器(如MacBook的Touch ID、iPhone的Face ID、Windows Hello、Android的指纹识别等)来完成身份认证,毋需再通过手动输入账号密码或是双因素认证码这种繁琐的认证手段,因此即使在网页上也能获得类似于原生应用的清爽身份验证体验。

对WebAuthn这项技术有兴趣的话,也可以参阅苹果官方的这个教程

可能是我孤陋寡闻,我尚未见过有网站用上过那么酷的身份验证API。(iPhone相机扫WebAuthn初始化二维码的那个界面好炫酷,还是第一次见。)而且它在Web App上的实现难度其实与双因素认证相差无几,哪怕早一个星期知道的话可能我就用上了,真是不巧。一口老血

诸位开发者如果有兴趣,不妨可以去尝尝鲜。

致未来

在上一篇Weekly提过,等Vue 3和Nuxt 3正式版发布之后,电波站大概会跟进并迎来一波重构。如今前两者已然成熟,但重构电波站的工作量却令现在的我望而却步。

电波站不知不觉已迎来了第五个年头,但经过好几年的积累,它的功能与代码结构变得愈加冗杂。再加上Vue 3和Nuxt 3的Breaking Change实在太多,很难想象久未接触前端和Node的我是否还能应付得过来。(仅仅是这周给电波站的后端事务调整了一下,那重构难度就已经让我对某保持42天一更新的游戏肃然起敬了。)而随着放弃对Node 16/Nuxt 2.x提供支持的包越来越多,每次npm更新时电波站那依赖库的deprecated(弃用)列表愈加长得令我肝颤,生怕这样下去,哪天我就不再能通过更新依赖库来给后端打补丁了。

为此,在过去的一年里我进行了一些尝试,包括但不限于:白嫖了M酱的服务器,用它搭了一个Typecho博客来跑我魔改版的VOID主题(开小号),以此来探索将电波站的文章迁移到Typecho的可能性。但发觉自己终究是个恋旧的人,很难再对电波站以外的平台产生归属感了,Velas电波站与电波站的文章,到头来谁也离不开谁。此举最后的结果是我魔改的VOID主题反被M酱白嫖了。

行吧,既然重构行不通,搬家也行不通,那我不如干脆就用Nuxt 3把前端重写了吧?(啊?)

于是,基于Vue 3和Nuxt 3的船新电波站(前端)便在筹备当中了。

新Velas的草图
新Velas电波站的草图(的一角)

然而去年画的这个第一版设计图被M酱一票否决了,真是出师不利。(难道是因为和现在的风格反差太大?)

不管怎么样,这事已经在缓慢推进中了。估计等鸡吃完米、狗舔完面、火烧断锁,船新电波站就上线了!

但毕竟还是更新文章比较重要,我想写的东西还有很多呢。(时间却完全不够用)

那就这样吧,回见!


© 本文文字内容著作权归Velas电波站所有。商业转载请联系站长获得授权;非商业转载请注明本文出处及文章链接,且未经站长允许不得对本文文字内容进行修改演绎。