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

▲ 人 生 相 谈

  其中想搞一个棉花糖环节,不过比较讨厌问卷星之类的充满广告的问卷平台。于是自己写一个!

  项目命名为 collow,取 cotton candy 的前缀与 marshmallow 的后缀拼接而成。

任务概要

  首先简要描述一下棉花糖的功能,经常看 vtuber 直播的读者可能会有所耳闻。棉花糖用于收集匿名的信件,主播在直播过程中吃棉花糖(打开这些想法并讨论)。之所以采用棉花糖而不是弹幕,是因为弹幕是实名的,有些话(尤其是牵涉个人隐私的)并不适合在弹幕里面说。

  目前在 vtuber 中流行的棉花糖网站是 marshmallow-qa.com ,但是对墙内非日语用户很不友好。国内存在各种提问箱(e.g. popi, peing, Tape),但往往需要绑定个人 sns 或 im 账号,换言之就是不干净。我们的目标是造一个棉花糖网站,支持如下功能:

  • 收集匿名信件。
  • 写信者可以修改或删除信件。
  • 主播可以查看或删除信件。
  • 主播可以设置提问箱为公开/私有。公开提问箱中,所有的匿名信向所有人展示;私有提问箱中,仅主播和写信者可以查看信件。

  首先,数据应该如何组织?显然一个主播可以开很多个提问箱,来应对不同场次直播的观众提问。于是我们设计为:每个主播可以开多个提问箱,每个提问箱可以容纳若干份信件。层次结构如下图所示:

▲ 信件数据的组织结构

  于是我们具体地定义一个主播的操作流程:

  1. 创建一个提问箱(box),选择其公开/私有属性。
  2. 将生成的 url 公布给自己的观众。
  3. 在后台收集信件。可以删去自己不喜欢的信件。
  4. 选择一些信件在直播中展示,并予以回答。

  显然,主播的权限不同于访客的权限,于是需要做出权限管理:主播需要创建一个带密码的账号;在登录之后才能管理自己的 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 提供给别人。

  至此,我们讨论完了所有的细节。接下来就是写代码 磨洋工 时间。


▲ 2021/01/31 晚进度。基本完成了“编写棉花糖”的界面。