用直播弹幕进行身份验证

最近 B 站弹幕游戏直播很热闹,但我总感觉有点单调。
比如弹幕修仙,参与之后,退出直播间,我仿佛从没来过,没有任何记录留下来过。
像是在公园用玩具枪打气球,在路边套圈,没有人会记得我来玩过。

如果游戏提供者想要记录一些用户数据,他当然可以把弹幕消息中的用户 uid 记录下来。
比如想知道有谁筑基,有哪些人结丹,那么游戏提供者就应该把游戏数据和弹幕消息中的 uid 做好映射,然后在 B 站的专栏发布自己记录的排名数据。
公开数据可以这么发布出来,但是游戏数据总有一些玩家私密的内容:储物袋里总有一些秘密不想给别人看到。让这类数据只有玩家本人能够看到,就需要做一次身份验证(登陆)。
因为弹幕游戏的玩家是以 B 站帐号为马夹产生游戏数据的,所以登陆行为的目的还是为了验证 B 站帐号身份。
常规做法是在 B 站注册为开发者,然后制作一个网站(公众号网页、小程序……),在传统的登陆流程中接入 B 站帐号登陆流程。
emmmm……实际上这很麻烦,认证和审核流程先不说了,搭建一个登陆功能完善的 Web 可能复杂度已经匹敌弹幕游戏了,有点舍本逐末。

这就需要设计一个相对安全,但是要足够简单的身份认证系统。
我把目光又转向了直播弹幕。

直播弹幕实际上弹幕 WS 通讯中的一个数据包,普通类型的弹幕包括 1. 发送者uid 2. 正文内容(20字以内)等,正常情况下,是不存在冒用 uid 发送弹幕的(吧?),所以我尝试提出一个简单的验证码流程,用作验证登陆请求确实是某个对应的 B 站用户发出的。
这个流程首先需要一个数据结构,作为验证状态的记录:
当一个用户想要登陆的时候,需要
在本地生成一个 UUID,用作表示当前客户端和开启的会话。发送自己的 uid 和 UUID 到服务器。
服务器收到打开请求,在数据库中新建一个 DanmuAuth 记录,储存 buid 和 UUID。生成并存储一个 VCode,我推荐选择比较好做正则匹配的前缀,把 VCode 返回给用户。
用户在一个指定的直播间将 VCode 作为弹幕发送。
服务提供者部署一个弹幕流侦听脚本,如果正则匹配到了 VCode 格式的弹幕,将其中正文和 uid 一并发给服务端处理。
服务端查询十分钟内的是否有符合 uid 和 VCode 的记录,如果有,则将 VerifiedCount 的值加一。
用户在前端发起“我已发送弹幕”的请求,通知服务器。
服务器查询 buid 、UUID、VCode 同时符合的记录,且其 VerifiedCount 大于一个阈值(这里是0),服务器生成 JWT 并删除这条 DanmuAuth 记录。
将 JWT 返回给用户,登陆成功。
这是一个比较简单的流程,我们将其用在了我们自己的直播工具 https://2some.one 上,它目前运行得很不错。
同时这个登陆流程我们实现了一个开源版本,https://github.com/tymon42/live-stream-commont-auth
基于它,你也可以尝试实现一个分布式的认证服务(更改一下 VerifiedCount 的阈值)。
有任何提议和问题,欢迎评论和 issues,请随意。