FitPiece:一个拼图游戏,最后把后端重写了
本来只是想做个上传图片就能玩的拼图小游戏,结果 CloudBase 登录卡了我两天,最后干脆自己写了一个 Node 后端。

FitPiece 是我做的一个 Web 拼图游戏:https://game.fitpiece.top/。
玩法很简单:上传一张图片,系统把它切成 3×3 到 6×6 的碎片,然后拖动拼回去。
一开始我以为这是个很轻的项目,前端画个棋盘,后端存一下图片和用户信息就差不多了。结果真正做起来,最麻烦的不是拼图逻辑,而是登录、上传、权限、安全这些“看起来很边角”的东西。
最后我把最开始用的云开发后端整个换掉,自己写了一个 Node 服务。
一开始,我用的是云开发
最开始后端用的是腾讯云开发(CloudBase)。对学生项目来说它确实方便:不用自己配服务器,也不用一开始就管数据库和存储。
前面进展很快,图片上传、数据保存这些都能跑。
直到我要做用户名密码登录。
CloudBase 支持自定义登录,但需要你的后端签发一个 JWT ticket 给它换 token。问题就出在这个 ticket 上:
- ticket 的格式要求很刁钻,字段错一个就报一个语义模糊的错
- 签名密钥必须是 1024 位
refreshToken相关字段的语义文档说得含糊,我试了无数种组合
我在这里卡了两天。最难受的不是报错,而是你不知道到底是哪一层错了:是 JWT 字段不对,还是签名不对,还是 CloudBase 那边的规则没理解对。
后来我意识到一件事:我本来是为了省时间才用云开发,但现在花在“理解云开发登录机制”上的时间,已经快超过自己写一个简单后端了。
第二天我把 CloudBase 整个删了。
自己造后端,反而简单了
新后端就是一个很朴素的 Node.js 服务:
- 数据:一个 JSON 文件当数据库(
db.json),用户量级根本用不着上 MySQL - 图片:直接存在服务器文件系统里
- 鉴权:自己签发 session token,32 字节随机 hex,存在数据库里,30 天有效
前端也不用 SDK 了,登录注册就是几个普通 fetch():
const res = await fetch("/fitpiece/api/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password }),
});
const { uid, token } = await res.json();
localStorage.setItem("fp_token", token);token 之后通过 Authorization: Bearer 请求头带上——不放在 URL 参数里,因为 URL 会被服务器日志、浏览器历史、Referer 头记录下来,等于到处撒 token。
换完之后,项目反而清楚了很多。哪里错了就看 docker logs,数据长什么样就打开 db.json,请求有没有带 token 也能直接查。
它没有 CloudBase 那么“高级”,但对这个项目来说,够用,而且可控。
一个学生项目,也该认真对待安全
游戏能玩之后,我没有马上收工。因为它有注册登录、有用户上传、有公共图库,已经不是一个纯前端 Demo 了。
我想借这个项目,把一个真实网站最基础的安全点过一遍。
密码绝不明文存
密码用 Node 内置的 scrypt 慢哈希,加随机 salt。
这个地方不能偷懒。哪怕只是学生项目,也不能把密码明文写进 JSON 文件里。
防时序攻击
校验密码时用了 crypto.timingSafeEqual 做恒定时间比较。
还有一个容易忽略的点:用户名不存在时,也跑一遍假的哈希。否则“用户名不存在”和“用户名存在但密码错”的耗时不一样,理论上会泄露哪些用户名被注册过。
// 用户名不存在时也烧掉同样的时间,抹平时序差异
if (!user) {
scryptSync(password, FAKE_SALT, 64); // burn time
return fail("用户名或密码错误");
}别信前端
公共图库只有管理员能传图。前端会把按钮藏起来,但后端还是要检查 user.admin。
前端的限制只是界面,不能当权限。
还有一串
- 登录注册限流:每个 IP 每 5 分钟最多 10 次,挡暴力破解
- 上传的图片校验文件头魔数(必须是真的 JPEG/PNG)+ 大小限制,防止有人传个伪装成图片的脚本上来
- 后端 API 容器不对外开端口,只有内网的 Nginx 能访问它,外面没法绕过 Nginx 直接打后端
还没做完的事
当时最大的遗留问题是:还没上 HTTPS。
这点其实挺别扭。你后端密码哈希、token 鉴权做得再认真,如果传输还是明文,安全性就打折。
这件事后来已经补上了:fitpiece.top 备案通过后,我把 FitPiece 单独放到了 game.fitpiece.top,并且走 HTTPS。现在它不再只是服务器上的一个临时路径,而是一个可以正式分享出去的小项目。
写在最后
回头看,FitPiece 最有价值的地方不只是拼图功能本身,而是那次“删掉重来”。
有些工具一开始很省事,但当项目需求开始变细,它可能反而会把你困住。这个时候继续硬凑,不一定比自己写简单。
这次我至少把注册、登录、上传、权限、限流、HTTPS 这些东西连起来做了一遍。很多概念以前只是知道,这次是真正碰到了。
去玩玩看吧,传张你喜欢的图片拼拼看。
靖淯茗
计算机专业在读,在 AI / Web / 数据库之间折腾。Build · Learn · Share。