之前写过一篇《从零到一》,记录了这个网站从无到有的过程。当时的方案是纯静态——Markdown 转 JSON,Nginx 直接配信,干净利落。但用了一段时间后,总觉得缺点什么:文章只能看不能互动,想评论没地方写,想收藏只能靠浏览器书签。是时候让网站"活"起来了。
为什么要改造
纯静态网站有它的好处:部署简单、速度快、几乎不用运维。但问题也很明显——没有用户系统,一切社交功能都无从谈起。
我想要的功能很明确:
- 登录:让用户有身份,不用每次都是匿名访客
- 评论:看完文章能说两句,也能回复别人
- 收藏:喜欢的文章能标记下来,下次方便找
这三个功能看起来简单,但每一个都需要后端支撑——需要知道"谁"在操作,需要把数据存下来。纯静态方案到这里就走不通了。
架构调整:重新引入后端和数据库
之前建站的时候其实考虑过前后端分离的方案,但当时内容以 AI 生成的静态文章为主,没有交互需求,就选了最简单的纯静态路线。现在需求变了,架构也得跟着变。
改造后的架构:
- 前端:React + Vite,基本不变,只是新增了登录组件、评论区、收藏按钮
- 后端:Express.js API 服务,处理认证、评论、收藏等接口
- 数据库:PostgreSQL,用 Prisma 做 ORM,管理用户、评论、收藏等数据
- 部署:Nginx 继续负责静态文件配信,同时反向代理 API 请求到 Express
文章内容的数据流没变——还是 Markdown → JSON → Nginx 静态配信。社交功能走另一条路:前端调 API → Nginx 代理 → Express → PostgreSQL。两条路互不干扰。
登录功能:Google 和 GitHub OAuth
自建用户名密码系统?算了,2026 年了,没必要自己管密码。直接上第三方登录,目前支持 Google 和 GitHub。

桌面端的体验很顺畅,点击右上角的登录按钮,选择 Google 或 GitHub,授权后跳回来就完事了。
第一次登录的用户需要完成注册,设置一个账户 ID 和显示名称:

账户 ID 是唯一标识,英文字母开头,支持英文、数字、下划线,3-20 个字符。显示名称就是其他用户看到你时显示的名字,可以随时改。
踩坑:微信里 Google 登录被拒
功能做好后分享到微信群里让朋友试试,结果第一个反馈就是"登录不了"。
微信内置浏览器打开链接后,点击 Google 登录,直接弹出了这个:

禁止访问:"DranixJ's Blog"的请求不符合 Google 的相关政策
错误 403:disallowed_useragent
原因很简单:Google 出于安全考虑,禁止在嵌入式浏览器(WebView)中进行 OAuth 登录。微信的内置浏览器本质上就是一个 WebView,所以直接被 Google 拒了。这不是我的代码有问题,而是 Google 的策略——它要求 OAuth 必须在"真正的浏览器"中完成。
解决办法也不复杂,微信提供了"用默认浏览器打开"的选项:

在微信里点击右下角的"..."菜单,选择"用默认浏览器打开",跳转到 Safari 或 Chrome 后就能正常登录了。
虽然多了一步操作,但这是 Google 的限制,没有太好的绕过方式。后续可以考虑加一个引导提示——检测到微信环境时,直接告诉用户"请用浏览器打开"。
评论和收藏
登录之后,评论和收藏就水到渠成了。
评论支持回复和 @提及,有新回复时会通知被 @的用户。收藏功能就是简单的标记/取消标记,收藏过的文章可以在导航栏的 FAVORITE 页面统一查看。
这些功能从技术角度来说都不复杂,核心就是 CRUD。但有了它们,网站终于从一个"只能看"的静态页面变成了一个有基本互动能力的平台。
总结
这次改造的核心就一件事:给纯静态网站加上用户系统。为此引入了 Express 后端和 PostgreSQL 数据库,支持了 Google/GitHub 第三方登录,实现了评论和收藏功能。
踩的最大的坑是微信 WebView 下 Google OAuth 被拒,这个问题目前只能靠引导用户用浏览器打开来解决。
后续还有不少想做的事情——通知系统、用户主页、更多的社交功能。但先到这里,一步一步来。
评论