写这篇网站的起因,是因为洛谷的一门助学课:

其中想搞一个棉花糖环节,不过比较讨厌问卷星之类的充满广告的问卷平台。于是自己写一个!
项目命名为 collow,取 cotton candy 的前缀与 marshmallow 的后缀拼接而成。
任务概要
首先简要描述一下棉花糖的功能,经常看 vtuber 直播的读者可能会有所耳闻。棉花糖用于收集匿名的信件,主播在直播过程中吃棉花糖(打开这些想法并讨论)。之所以采用棉花糖而不是弹幕,是因为弹幕是实名的,有些话(尤其是牵涉个人隐私的)并不适合在弹幕里面说。
目前在 vtuber 中流行的棉花糖网站是 marshmallow-qa.com ,但是对墙内非日语用户很不友好。国内存在各种提问箱(e.g. popi, peing, Tape),但往往需要绑定个人 sns 或 im 账号,换言之就是不干净。我们的目标是造一个棉花糖网站,支持如下功能:
- 收集匿名信件。
- 写信者可以修改或删除信件。
- 主播可以查看或删除信件。
- 主播可以设置提问箱为公开/私有。公开提问箱中,所有的匿名信向所有人展示;私有提问箱中,仅主播和写信者可以查看信件。
首先,数据应该如何组织?显然一个主播可以开很多个提问箱,来应对不同场次直播的观众提问。于是我们设计为:每个主播可以开多个提问箱,每个提问箱可以容纳若干份信件。层次结构如下图所示:
于是我们具体地定义一个主播的操作流程:
- 创建一个提问箱(box),选择其公开/私有属性。
- 将生成的 url 公布给自己的观众。
- 在后台收集信件。可以删去自己不喜欢的信件。
- 选择一些信件在直播中展示,并予以回答。
显然,主播的权限不同于访客的权限,于是需要做出权限管理:主播需要创建一个带密码的账号;在登录之后才能管理自己的 box. 为了实现这个业务,数据库中应当有:
- 用户表:字段为邮箱(主键,采用 Gravatar 来展示用户头像)、昵称及其密码 hash。
- 提问箱表:字段为提问箱 id(主键)、创建者。
- 信件表:字段为信件 id(主键)、信件内容、发送时间、所属的提问箱。
为了做一个干净的应用,我不打算要求提问者注册账号。这就产生了一个问题:如何将提问者与访客区分开?
我们采用的解决方案是 url 鉴权。在生成一个信件的同时,后端产生一个唯一的管理 token 字符串,并返回给用户:
https://example.com/msg/<message id>/ # 信件展示
https://example.com/msg/<message id>/<token>/ # 信件管理
仅当用户访问带正确 token 的地址时,用户可以管理这个信件。当然,用户需要记录下这个管理 url,一旦丢失就不能找回。在这个地址上,用户修改或删除信件,发送请求到后端 api,必须带有正确的 message id 和正确的 token. 这并不难以实现。
讨论一下如何管理 token. 显然可以临时随机生成并存放到数据库;但这给数据库带来了额外的压力。我们采用密码学的解决方案:HMAC.
token = HMAC(key=SECRET_KEY, msg=message_id)
其中 SECRET_KEY
是站点配置,需要保密。由于不知道 SECRET_KEY
的情况下无法伪造出任何信息的 HMAC,如果用户知道管理 url,我们就相信他是生成这个 message id 的人士,因为 message id 是全局唯一的,我们不会把相同的 message id 提供给别人。
至此,我们讨论完了所有的细节。接下来就是写代码 磨洋工 时间。
