广告
广告
广告
前言权限控制是企业级应用中最容易"看起来做了,实则一捅就破"的模块。常见的伪 RBAC 实现往往是在 Controller 里直接判断 user.role === 'admin',把角色硬编码散落在各处,后期维护极其痛苦。本文将从架构设计出发,基于 NestJS + Prisma + Redis + CASL 构建一套真正可扩展的 RBAC 体系,覆盖以下核心问题:纯角色判断为何不够?如何建模"资源:动作"级别的原子权限?NestJS 的守卫管道中,认证与授权如何职能分离?每次请求都查数据库权限太慢,如何用 Redis 将查询压缩到毫秒级?用户拥有 article:d...
NestJS 统一响应体设计:信封格式与正确 HTTP 状态码在前后端分离项目中,API 响应格式会同时影响前端开发体验、错误处理和系统可观测性。本文以 NestJS 为例,设计一套“信封格式 + 正确 HTTP 状态码”的统一响应方案,覆盖成功响应、异常响应和 Swagger 文档三个部分。本文默认读者已经了解 NestJS 的拦截器、异常过滤器,以及上一篇《NestJS 生产级错误过滤方案》中的 Prisma 过滤器链路。[hide]一、先确定响应格式1.1 两种常见方案业界主要有两种 API 响应风格。HTTP 语义派(Stripe、GitHub、Google API):成功请求返...
前言:为什么需要生产级错误过滤默认响应的局限NestJS 内置的异常处理机制已经相当完善,但在生产项目中仍然存在明显不足:格式不统一:不同层抛出的异常,响应结构各不相同。HttpException 返回 { statusCode, message },未捕获的 Error 返回 500 的通用格式,Prisma 错误则直接泄露为 500 且没有任何业务上下文。泄露内部细节:默认情况下,数据库错误、堆栈信息、内部路径等敏感内容可能出现在生产环境的响应体中。可观测性差:没有统一的日志格式,无法关联请求链路,难以在监控系统中定位问题根源。生产环境的核心诉求诉求说明统一格式前端对接时只需处理一种...
前言TypeORM 是 Node.js 生态中历史最悠久的 ORM,也是 NestJS 官方文档中首推的数据库解决方案之一。它以装饰器驱动的 Entity 定义为核心,支持 Active Record 与 Data Mapper 两种模式,与 TypeScript 有着天然的契合。相比 Prisma 的 Schema-first 理念,TypeORM 更贴近传统 ORM 思想:Entity 类既是数据库表的映射,也是业务对象。对于习惯 Java/Spring 或 C#/EF 体系的开发者来说,TypeORM 的上手成本更低。本文使用 Data Mapper 模式(Repository 模...
前言Prisma 是 Node.js 和 TypeScript 生态中最受欢迎的 ORM 之一。相比 TypeORM,它提供了更强的类型安全性、更直观的 Schema 语法,以及自动生成的迁移文件。Prisma v7 已全面转向 ES Module,而 NestJS 默认使用 CommonJS,因此需要做一些特殊处理——本文会详细说明。本文基于 Prisma v7 和 NestJS 最新版,从安装到生产级集成,覆盖以下内容:正确安装配置 Prisma,与 ConfigService 和日志系统整合使用 prisma.config.ts 统一管理 schema、迁移、seed 与数据源配置...
前言在上一篇《10 NestJS JWT 身份验证完全指南》中,我们完整实现了基于 JWT 的身份验证体系,其中已涉及 Argon2id 哈希和时序攻击防护。但密码安全不止于此 —— 注册和登录接口是攻击者最频繁的目标,一旦设计失误,后果往往是大规模账号泄露。本文聚焦于密码在整个生命周期(注册 → 存储 → 验证 → 重置)中的威胁模型和防护实践,所有代码示例均为生产级实现,可直接集成到已有项目中。阅读本文需要完成《10 NestJS JWT 身份验证完全指南》的实践,或具备等同的 NestJS 认证体系基础。[hide]第一部分:威胁模型在写代码前,先明确我们要对抗的攻击类型。不理解攻...
NestJS JWT 身份验证完全指南前言JWT(JSON Web Token)是目前 RESTful API 身份验证领域的主流方案。其核心优势在于无状态性——服务端无需维护会话存储,token 本身即携带经签名保护的身份信息。然而,仅理解 JWT 的基本签发与验证远远不够。在实际工程落地中,还需要系统性地考量以下问题:安全边界:payload 明文可解码,哪些字段可以放,哪些绝对不能放?token 生命周期:单一长期 token 的泄露风险如何通过双 Token 策略加以控制?主动吊销:JWT 无状态的特性与"立即登出"的业务需求之间,如何取得平衡?密码安全:bcrypt 之外,为何...
前言在前后端分离的项目中,API 文档是前后端协作的核心契约。手动维护文档不仅繁琐,还容易与代码脱节。@nestjs/swagger 基于 OpenAPI 规范,通过装饰器直接从代码生成交互式 API 文档,做到了文档即代码。本文基于 @nestjs/swagger v8(NestJS v10/v11),覆盖从基础配置到生产级最佳实践的完整流程。[hide]安装pnpm add @nestjs/swagger一、基础配置(main.ts)在 main.ts 中初始化 Swagger,这是所有配置的起点。// src/main.ts import { NestFactory } from ...
前言在了解DTO与Entity的区别之前,我们先来了解一下它们在项目中的数据路径。[客户端 Client] │ ▼ (1. 携带 Request DTO) [Controller] ── (2. 校验与格式转换: ValidationPipe) │ ▼ (3. 传递 DTO 或 解构参数) [Service] ──── (4. 业务逻辑,将 DTO 转换为 Entity 或操作 ORM) │ ▼ (5. 写入/读取 Entity) [Database] │ ▼ (6. 返回 E...
前言相比较Redis,Nestjs官方还提供了一个更为通用的缓存模块 @nestjs/cache-manager,它是基于 cache-manager 封装的,支持多种缓存存储方式(内存、Redis、Memcached等),并且可以通过配置来切换不同的缓存存储。常见的缓存场景包括:数据库查询结果缓存接口请求结果缓存统一不同缓存存储的接口在与Redis结合使用,已经是生产环境中最常见的缓存方案之一。如果条件允许,可以配合使用。[hide]核心依赖安装# 核心依赖 pnpm add @nestjs/cache-manager cache-manager全局与异步配置常见做法是在 AppMod...
前言在Nestjs项目中使用Redis时,我们可能需要考虑下,是否有必要使用它?如果内存缓存就够使用了,项目也没有多节点方案,也不需要考虑重启后缓存数据丢失的问题,那么使用Redis就没有必要了。因为Redis是一个独立的服务,使用它会增加系统的复杂度和维护成本。[hide]一、 环境搭建与模块注册1. 安装依赖由于 ioredis 在v5.0版本后已经内置了 TypeScript 类型定义,我们只需要安装核心包:npm install @nestjs-modules/ioredis ioredis2. 异步模块注册(生产环境标准配置)通过 forRootAsync 结合 ConfigS...
前言当Nestjs项目越来越复杂的时候,构建速度成为了开发者最关心的问题之一。我最近才了解到 SWC 构建器,为此特意将SWC与最新的 TypeScript 7.0 语言特性进行对比。[hide]2026 年 TS/Node.js 构建生态:SWC 与 TypeScript 7.0 选型演进1. SWC (Rust) vs TypeScript 7.0 (Go Native) 性能区别SWC (Rust 实现):定位为代码转译器(Transpiler)与打包器(Bundler)。SWC 专门负责快速剥离 TypeScript 类型标注,将其转换为目标 JavaScript 代码。由于跳过...
前言你是否也经历过这样的“上线惊魂”?某天你对 API 的返回结构做了优化,将 name 拆分成了 firstName 和 lastName,部署上线后一切完美。然而半小时后客服被打爆——许多未更新 APP 的老用户打开页面直接闪退,因为客户端无法解析新的数据结构。你不得不加班倒回代码,或者在后端写满极其恶心的 if-else 去兼容老版本……在真实的生产环境中,breaking changes(破坏性变更) 几乎不可避免。但与 Web 网页不同,移动端 APP、微信小程序以及第三方 SDK 的更新存在巨大的滞后性,你无法强制所有用户在同一秒升级客户端。许多初级开发者在面对多版本需求时,...
前言程序运行时,你怎么知道它是否正常?出问题了,你怎么知道哪一步出了错?这些问题的答案就是 日志。日志是程序运行时留下的"行动记录",是排查问题最重要的工具。我们该如何在 NestJS 中正确地处理日志呢?本文将从日志等级、日志存储位置、NestJS 内置 Logger、第三方日志库(Winston、Pino)、全局异常过滤器、请求日志中间件等方面进行详细讲解。二、日志等级日志按照严重程度分为以下等级(从低到高):等级说明Verbose最详细的信息,例如接口耗时,非必要不使用Debug调试信息,例如接口入参、返回值,仅开发阶段使用Log通用日志,记录普通运行信息Warning警告,例如即...
前言在 NestJS 的日常开发中,@nestjs/config 是我们最常用的模块之一。大多数开发者对它的印象可能还停留在“读取 .env 环境变量并注入到 ConfigService 中”。其实,@nestjs/config 提供了许多非常实用的进阶功能。本文将介绍其中三个实用的拓展用法:扩展变量(Expandable variables)、环境变量加载钩子(Environment variables loaded hook) 和 条件模块配置(Conditional module configuration)。1. 扩展变量(Expandable variables)场景与痛点在配...
前言最近在重装服务器的时候,发现恢复网站真的超级累,不是这个插件要配置账号密码,就是那个插件依赖不存在,要安装,等把环境配置完后,又开头头疼网站创建了。在之前,我的博客是有两个域名可以访问的:主域名:www.mulingyuer.com副域名:mulingyuer.com为了方便访问,我都是给副域名做301或者302重定向到主域名上,这样访问副域名的用户就会自动跳转到主域名上。但是这就涉及到一个问题,我需要在宝塔创建两个网站,分别绑定两个域名,然后都要申请SSL证书,然后副域名还要设置301或者302重定向到主域名上,这样就显得非常麻烦。特别是当我的站点多的时候,1个网站要配置2次,2个...
前言如何在NestJS中管理环境变量,是一个后端项目开发中非常重要的环节。环境变量的管理不仅影响应用的配置灵活性,还关系到应用的安全性和可维护性。在NestJS中,我们可以通过Config模块来实现对环境变量的集中管理和配置。[hide]@nestjs/config 基础与默认机制1. 模块安装与基础初始化首先需要安装 NestJS 官方的配置模块:pnpm install @nestjs/config在根模块 AppModule 中注册 ConfigModule:// src/app.module.ts import { Module } from "@nestjs/comm...
前言在前端开发中,你可能经常遇到这样的窘境:项目 A 比较老,必须用 Node 14 才能运行。项目 B 是新项目,要求用 Node 18 以上。每次切换项目,都要手动输入命令切版本,一旦忘了切换就会报一堆错。今天,我们就来彻底解决这个问题!本文将手把手带你安装和配置目前业界最快、最流行的 Node 版本管理器 —— FNM (Fast Node Manager)。配置完成后,只要你在终端 cd 进入某个项目,Node 版本就会自动切换,实现完全无感开发。什么是 FNM?FNM 是基于 Rust 语言开发的一个 Node.js 版本管理器。它的特点就是极快,比老牌的 nvm 快上百倍。而...
前言在多项目、团队协作或 Monorepo 仓库(如 pnpm monorepo)中,不同的项目往往依赖不同版本的包管理器(如 pnpm 9 vs pnpm 10)。每次手动重拆和安装全局包管理器不仅麻烦,还容易因版本不一致导致依赖解析冲突。Node.js 官方内置的核心工具 Corepack 解决了这个问题。它是一个“包管理器代理处理器”,可以根据项目 package.json 的配置,自动下载、切换并运行对应版本的 pnpm、yarn 或 npm。下面是一份面向新手的简明实践指南。核心工作原理不开启 Corepack:你在终端输入 pnpm install 时,系统运行的是你通过 n...
前言在阅读一些成熟项目、开源库或者打包后的代码时,我们偶尔会看到这样的写法:void someAsyncTask();或者:value === void 0再或者老代码里的:<a href="javascript:void(0)">点击</a>第一次看到时很容易困惑:void 是什么?它是在取消执行吗?为什么调用异步函数前面要加一个 void?void main() 又是什么意思?本文会从日常开发最常见的场景讲起,解释 void 的基本语义、为什么它常被用来忽略 Promise,以及一些历史代码中常见的写法。看完之后,你至少能做到两件事:读懂别...
前言最近,随着 Codex、VSCode的Agents模式、Claude Desktop 等 AI 编程辅助工具的火爆,worktree(工作树)这个功能开始频繁出现在开发者的视野中。其实,git worktree 并非新事物,它是 Git 2.5(2015 年)就引入的“神兵利器”。本文将用最通俗的语言,带你彻底搞懂这个能让开发效率翻倍的“高阶操作”。为什么要用 Git Worktree?在日常开发中,你一定遇到过以下三个“破防瞬间”:痛点一:紧急修 Bug,代码写了一半无法 commit日常场景:你正在 feature 分支写新功能,代码改得乱七八糟,连编译都通不过。突然接到紧急线上...
前言在日常开发的时候,常常会遇到这样两种情况:1. 模块/路径找不到(线上崩溃)本地开发、测试一切正常,代码合并提交一气呵成。然而,一到线上 CI/CD 部署构建,或者同事拉取代码,就直接报“找不到模块/路径”的错误崩溃了!排查了半天,你一拍大腿:原来是自己把文件夹 app/components/layout 改成了 app/components/Layout(首字母 l 改为了大写 L),或者把 utils.js 改成了 Utils.js,而 Git 居然完全没有检测到这个修改!2. 目录名或文件名修改没反应有时候我们可能会将目录名或文件名由不规范的命名方式改成规范的命名方式,比如 c...
前言在现代前端开发中,一个健壮、易用且与业务解耦的请求模块是项目成功的基石。本教程将带你一步步实现项目中现有的 Axios 封装方案。我们将实现以下企业级核心功能:核心与业务解耦:核心请求机制不依赖任何 UI 框架或状态管理库,可在任何 JS 环境中复用。高内聚装配层:通过一个装配文件,将项目特有的 Token 获取、路由跳转、Toast 提示等业务依赖注入到核心机制中。无感 Token 刷新:当遇到 401 Unauthorized 错误时,自动暂停后续请求,刷新 Token 成功后无感重发原请求。失败自动重试:集成 axios-retry,在网络波动或超时时自动重试,并提供重试上限的...
前言在前两篇文章中,我们完成了 Vue Query 的思维转变并掌握了基础实战。然而,在真实的中大型项目中,我们往往会遇到许多刁钻、复杂的业务需求。今天,我们将分享 4 个应对复杂场景的高级套路,帮助你彻底玩转 Vue Query。[hide]优雅的 Key 层次设计与全局缓存失效业务场景在需要登录鉴权的项目中,当用户点击“退出登录”时,我们必须立即清空所有与该用户相关的敏感接口缓存。否则,当下一个用户登录时,可能会短暂看到上一个用户的数据,造成严重的数据串线和安全隐患。如果一个一个去手动清理 user-detail、notice-list、billing-history,不仅代码极其繁...
前言在上一篇文章中,我们探讨了为什么要引入 @tanstack/vue-query 以及它与 Axios 的协同关系。今天,我们将正式进入实战阶段,手把手教你如何在 Vue 3 项目中搭建 Vue Query 的骨架,掌握其最核心的 API 与配置,并深入探讨如何利用调试工具和轻量级缓存更新策略提升开发效率。[hide]基础配置:搭建 Vue Query 的骨架在 Vue 3 项目中集成 Vue Query 非常简单,主要分为两步:初始化 QueryClient 和注册插件。第一步:初始化 QueryClient我们在项目根目录的 src/plugins/tanstack/vue-que...
最近评论