使用 FastSchema、Next.JS、NextAuth.js v5 和 Chakra UI 构建 DEV.to 风格的多用户博客(2)—— 设计与实现

1、DEV Community 特点

DEV Community(以下简称 DEV)是拥有数百万开发者的纯技术社区,它界面简洁,页面响应速度快。

虽然其每个页面有大量的文章列表和链接,也有赞助商广告,但视觉效果并不觉得屏幕满。

DEV 的代码是开源的(https://forem.com/)。主编程语言 Ruby。采用 Ruby on Rails 框架、经典的 MVC 架构,代码结构很清晰。

2、功能设计

2.1 用户控制台(Dashboard)

DEV 的用户控制台(Dashboard)很好地体现了其设计思想,UI 简洁、紧凑,功能一目了然,操作方便。

其中 Analytics 是很出彩的部分。

FastSchema 有内置控制台,简约风格,布局拉得比较开,主要功能不突出。当然,这可能跟其定位有关。

这个我参考 DEV 的 Dashboard 做了一个。包括:迷你统计状态卡片、 Posts、Drafts、Follower、Following users。

用户菜单的其他部分:Create Post、Reading List 和 Settings 都做了。Analytics 有时间再看。

Settings(设置部分)主力完成了 Profile 页面。

密集内容型的网站,不太能接受无限下拉刷新的设计。视频图片类的还好点。所以分页设计采用点击 Load more 加载下一页。

2.2 用户模式(Schema)

FastSchema 的 User、Role 和 File schema 是内置的。用户创建的 schema 多数与这几个 schema 有关联,这时是需要在后台手工操作的!稍有不便。

举个例子,Auth.js 在提供商返回的用户结构中除了 id、name、email 之外(这几个字段是 users 表中有的),还有一个 image 字段 users 表中没有。你可以在后台添加进去,但这样不确定在系统代码中是否有对此字段进行处理。所以我是另建了一张 profile 表,在 profile 中处理。

FastSchema 各 Schema 主键为 ID,类型 uint64。这些在其 REST api 中有直接 RUD 的、支持 pathname 参数的API。为简化查询、提高查询效率,不为各 schema 另设 slug 字段。

2.3 用户认证

FastSchema 使用 JWT(JSON 网络令牌)进行身份验证。用户密码登录这一块儿与 NextAuth.js(Credentials provider) 很好对接。

用户登录时,服务器将生成一个 JWT 令牌并将其发送回客户端。我们在客户端将其保存在 session 里。并在每次请求时将其设置在请求头 Authorization 中、发送回服务器。

OAuth 认证这块儿有点问题。目前,FastSchema 内置的第三方认证支持 GitHub 和 Google。而 Auth.js 内置了对 Google、GitHub、Twitter、Keycloak、Okta 等 80 多个提供商(providers)的支持。因此我选择了 Auth.js,后端需要做适配。

只做了 GitHub 的适配。近期 GitHub 访问尤其不畅。每次在认证回调的时候连接被终止。未能完整地完成测试。应该是 ok 的。

Google、Twitter 访问不了,就算了。

2.4 用户授权

FastSchema 内置基于角色的访问控制 (RBAC),支持自定义规则,可精确管理用户对所有资源的访问。

FastSchema 的 RBAC 功能是在服务端控制,修改即时生效。规则是可以自定义的。

FastSchema 默认有三个角色(Roles):Admin,User,Guest。Guest 无任何权限。

本设计重在实现功能。不改变角色。Guest 分配 POST 的 GET\LIST 权限。

授权采用后端的 RBAC 粗粒度控制 + web 端 NextAuth.js session 机制结合的方式控制用户访问权限。

举个例子,用户登录之后,在控制台页面能看到的文章,是经过 "filter: {user_id: {$eq: userId} as FilterObject}" 过滤过了。只能看到和编辑自己的文章。

FastSchema 有自定义规则的功能,不放心的话可以在规则里再加一层过滤。

现在,用户是可以 Like 和收藏自己的文章的。如果不允许,可以在 web 端发起请求之前处理下。

2.5 评论(comments)

没有 comments 代码。只有 comments_count 字段 :)。是为演示效果而模拟的。在 Next.js 官方代码库中有个基于 Redis 的评论 demo,可参考添加。

2.6 搜索自动完成

在 React 项目的 Navbar 中做这个是自讨苦吃。还好实现了!只是实现了而已。目前没有加 debounce,回车进入搜索页面。

2.7 用户交互

DEV 的 Reactions 有 Like、Unicorn、Exploding Head、Raised Hands 和 Fire 5 种反应。时间关系,就做了一个 Like。 

Reading List 相当于是书签(Bookmark),这个做了。

Follow 了某用户,相对于订阅了该用户的文章。在用户登录之后,首页应该有一个 Following 的 Tab。这个没做。

要实现这个,通过 FastSchema 的关联查询、过滤功能实现不难。

2.8 其他功能点

想到哪写到哪。还有很多功能点没有时间写了。有时间的话再在这篇文章里补充……

web 端的代码已上传。有兴趣的可自行了解下。

3. 关于 FastSchema

上篇说到写了一个计数器的 HOOK,这是利用 OnPreResolve 钩子,在读取 Post 之前执行文章浏览数 +1。

SEEDER 是为生成实验测试数据的。

FastSchema 的插件系统是基于 Goja 的,所以插件是要用 JavaScript 来写。

这个我写了一个 tagstat freq 插件,是用来统计 Tag 被引用的频次的。可以放到系统 CRON 中定期执行。

被正确识别到的插件,作为资源,可以在后台赋予给角色。

使用的变量名 MAIL 与 系统变量 MAIL 相冲突的小问题,可以通过在 fs 配置中加入 MailConfig 来避开。这需要 15 行代码。

4. 后记

虽然 DEV 我也经常访问(DEV 是能正常访问的少数外国技术社区)。但真正动作去做这一个模仿,是受到这位越南开发者的 repo(https://github.com/spicy-tomato/tech-blog)的启发和影响。不得不说其中的 new-user 组件路由守卫做得很巧妙。

还有 https://github.com/zwelhtetyan/dev.to-clone,尽管是它是基于 Firebase,看不到运行效果。但 zwelhtetyan 对 Chakra UI 的娴熟运用,让我从中学习良多。

还有 https://github.com/MA-Ahmad/dev.to-clone,首页模仿得太到位了,达到以假乱真的地步。

也用到你们的组件或借鉴了你们的思想写了一些组件,一并表示感谢。还有其他的就不一一细说了,感谢你们,感谢开源。

喜欢:
0
去到顶部