如何使用 NestJS 集成 Passort 和 JWT Token 实现 HTTP 接口的权限管理

💡 如果你不希望其他人可以随意进出你的房子,那么你需要给你的房子上个锁。

前言

开发一个接口很容易,开发一个具有安全性的接口却不容易。成熟的后端服务项目最注重的一点就是如何保护系统的数据安全,不能让用户无脑的访问操作所有的数据,这是不合理更是极度危险的行为。

NestJS 作为企业级后端开发框架,自然会提供一套权限校验的方案,本文基于NestJS的passort方案,结合 jwt token 完成对系统服务的保护。

操作步骤

💡 给你的服务装上防盗锁,只允许有钥匙的人进入。

一、安装依赖库

首先需要在nestjs项目中安装特定的依赖库

javascript 复制代码
npm install @nestjs/passport passport @nestjs/jwt passport-jwt -S
npm install @types/passport-jwt -D

二、引入 Passort 和 JWT 模块

身份认证是由passort模块提供主要框架,具体的校验能力我选择通过jwt完成用户信息验证,即引入jwt相关的nestjs模块;

javascript 复制代码
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({
      secret: 'your-secret-key', // TODO: 你需要放入自己的密钥,或者从环境变量中提取
      signOptions: { expiresIn: '1d' }, // 这是可选的
    }),
  ],
  providers: [AuthService, JwtStrategy],
})
export class AuthModule {}

三、创建 JWT 策略

需要创建一个JWT策略,这个策略服务是用于处理JWT的校验与解析。

javascript 复制代码
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Injectable, UnauthorizedException } from '@nestjs/common';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: 'your-secret-key', // TODO: Replace with your key
    });
  }

  async validate(payload: any) {
    // TODO: Add your validation logic
  }
}

四、Controller方法使用验证装饰器

当完成JWT策略创建并注入到AppModule模块,即可在服务接口上使用 AuthGurd 装饰器进行用户身份的验证。

javascript 复制代码
import { Controller, Get, UseGuards, Request } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  constructor() {}

  @UseGuards(AuthGuard('jwt'))
  @Get()
  getHomeInfo() {
    return {
      code: 0,
      message: 'ok',
      data: {
        name: 'https://www.levenx.com',
      },
    };
  }
}

访问 http://localhost:3000

由此发现请求首先会经过JWT策略的身份验证,需要保证请求的header中包含 Authorization 字段。

五、生成 JWT Token

步骤五的截图中看到,当客户端没有做任何处理就发起请求时,直接被passport拦截并返回401。

为了通过身份验证拦截,客户端发起请求时需要在请求Header上携带 Authorization字段,并且value值必需满足 Bearer + jwt token 格式,具体实现可参考:

javascript 复制代码
fetch('http://localhost:3000', {
  headers: {
    'Authorization': `Bearer ${jwtToken}`
  }
})

客户端如何获取到 **jwt token**字符串?

从步骤二中,我们已经在AppModule引入了 JwtModule,它在全局提供了生成JWT Token的服务 JwtService,通过 JwtService即可生成JWT Token字符串。

typescript 复制代码
import { JwtService } from '@nestjs/jwt';
import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthService {
  constructor(private readonly jwtService: JwtService) {}

  async sign() {
    return this.jwtService.sign({ userId: 123456 });
  }
}
javascript 复制代码
@Controller()
export class AutoController {

  @Inject(AuthService)
  private readonly authService: AuthService;

  @Get('/login')
  async login() {
    const token = await this.authService.sign();
    return {
      code: 0,
      message: 'ok',
      data: {
        token,
      },
    };
  }

}

通过访问 http://localhost:3000/login获取JWT Token字符串

客户端获取到 Token 字符串后需要持久化保存起来,并且后续接口请求Header中携带上。如果JWT 是合法有效、在有效期内,通过了AuthGuard的校验,即可正常访问受保护的接口。如果JWT无效,AuthGuard会拦截请求,用户会收到401错误码。

总结

本文介绍了如何对请求进行信息校验,对于没有携带Token的请求进行防御性拦截,这保证了基础的保护作用。但是还存在其他更细致的权限问题没有解决,比如不同的用户对于资源有不同的操作权限(有的用户只能查看资源,有的用户可以修改删除资源),这类问题需要我们对每个用户的权限进行更加清晰的管理。

很快我会输出一篇关于NestJS如何细粒度的权限管理的实操教程,敬请关注。

相关推荐
时光追逐者1 分钟前
MongoDB从入门到实战之MongoDB快速入门(附带学习路线图)
数据库·学习·mongodb
头顶秃成一缕光24 分钟前
Redis的主从模式和哨兵模式
数据库·redis·缓存
AIGC大时代26 分钟前
高效使用DeepSeek对“情境+ 对象 +问题“型课题进行开题!
数据库·人工智能·算法·aigc·智能写作·deepseek
博睿谷IT99_27 分钟前
数据库证书可以选OCP认证吗?
数据库·oracle·开闭原则·ocp认证
乐维_lwops39 分钟前
数据库监控 | MongoDB监控全解析
数据库·mongodb·数据库监控
观无39 分钟前
Redis安装及入门应用
数据库·redis·缓存
Run1.1 小时前
深入解析 Linux 中动静态库的加载机制:从原理到实践
linux·运维·服务器
柏油2 小时前
MySql InnoDB 事务实现之 undo log 日志
数据库·后端·mysql
码农hbk2 小时前
linux ptrace 图文详解(七) gdb、strace跟踪系统调用
linux·服务器
DolphinScheduler社区2 小时前
白鲸开源WhaleStudio与崖山数据库管理系统YashanDB完成产品兼容互认证
数据库·开源·认证·崖山数据库·白鲸开源