在 Next.js 应用中使用 Passport、JWT 和 DDD 实现登录
Source: Dev.to
Introduction
我最初构建了一个需要登录功能的 Next.js 应用。为此,我选择了 Passport(一个成熟的认证库),并使用 JWT 作为已认证身份的安全凭证。这在目前来看是相当标准的做法。
Architecture Overview
我希望应用遵循 领域驱动设计(DDD) 原则,因此明确将系统拆分为三个组件:
Backend
- 负责数据持久化和业务规则
- (API / GraphQL、用户模型、权限、会话有效性)
OAuth Express Server
- 完全拥有 Passport 的自定义 Express 服务器
- (策略、登录编排、令牌签发)
Frontend
- 只负责 UI 和用户交互的 Next.js 应用
Goals of the Separation
- 认证应能够独立于前端技术复用。
- 前端可以更换。
- 后端可以更换。
- OAuth 可以在项目之间复用,而无需重写登录逻辑或将 Passport 与特定 UI 框架耦合。
Next.js as a Bridge
Next.js 同时在服务器和浏览器中运行,形成了一个强大的快捷方式:
- Next.js 在 服务器端 调用 OAuth 服务器。
- 它在 浏览器之外 接收 JWT。
- 它将该 JWT 转发给客户端并存入 Cookie。
从开发者的角度来看,这种方式既优雅又简单。然而在架构上会出现一个细微的转变:前端现在参与了认证信息的存储。尽管 Passport 位于别处,Next.js 仍然成为信任边界的一部分,因为它:
- 在服务器端接收 JWT
- 决定如何在浏览器中持久化它
Next.js 能够同时在服务器端和客户端运行的特性,使其非常适合实现认证流程。在此架构中,Next.js 可以安全地在服务器上接收 JWT,并在同一次执行路径中将其以 Cookie 形式持久化到浏览器。
Benefits of Applying DDD
- 认证逻辑位于 前端之外,而不是埋在单一框架内部。
- 责任保持清晰,边界明确。
- 前端仍然可以利用 Next.js 的能力,而不必耦合认证细节。
关键的收获是登录功能只是结果的一部分。通过分离关注点,三个组件中的两个现在可以在另一个项目中保持不变地复用。
Repository
如果你想实际查看该架构的实现,本文中描述的 OAuth 组件已作为公共仓库提供:
👉
该仓库包含了独立的 OAuth Express 服务器,拥有 Passport 实现和 JWT 签发,完全如上文所述。它旨在跨项目复用,且不依赖于前端框架。