nestjs 中 JWT 鉴权登录

读者来稿 · song-shao与 batype 的 AI 分身对话整理

·314 字 · 约 1 分钟#NestJS#Node.js#JWT (JSON Web Tokens)

在 NestJS 中使用 JWT(JSON Web Token)进行鉴权和登录是一个非常常见的做法。下面是一个示例,展示如何实现 JWT 鉴权和登录。

前置条件#

确保你已经安装了 NestJS,并且你的项目中已经安装了以下依赖:

  • @nestjs/jwt
  • @nestjs/passport
  • passport
  • passport-jwt
  • bcryptjs(可选,用于哈希密码)

你可以使用以下命令安装这些依赖:

npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcryptjs

步骤#

1. 创建 AuthModule#

生成一个新的模块,用于处理身份验证。

nest generate module auth

2. 创建 AuthService#

AuthModule 中创建一个 AuthService,负责处理用户验证和 JWT 生成。

nest generate service auth

在生成的 auth.service.ts 中:

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcryptjs';

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

  async validateUser(username: string, pass: string): Promise<any> {
    // 这里通常调用用户服务从数据库获取用户
    const user = { username: 'test', password: await bcrypt.hash('password', 10) }; // 示例用户
    const isPasswordMatching = await bcrypt.compare(pass, user.password);

    if (user && isPasswordMatching) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}

3. 设置 JWT Strategy#

创建一个 JwtStrategy,用于提取和验证 JWT。

nest generate class auth/jwt.strategy

jwt.strategy.ts 中:

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: 'your_jwt_secret_key', // 请确保使用环境变量存储密钥
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}

4. 配置 AuthModule#

auth.module.ts 中配置模块和服务:

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    PassportModule,
    JwtModule.register({
      secret: 'your_jwt_secret_key', // 请确保使用环境变量存储密钥
      signOptions: { expiresIn: '60m' },
    }),
  ],
  providers: [AuthService, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}

5. 实现 AuthController#

创建一个控制器来处理登录请求。

nest generate controller auth

auth.controller.ts 中:

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthGuard } from '@nestjs/passport';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @UseGuards(AuthGuard('local'))
  @Post('login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}

6. 使用 Guards 保护路由#

在需要保护的路由上使用 AuthGuard

import { Controller, Get, UseGuards, Request } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller('profile')
export class ProfileController {
  @UseGuards(AuthGuard('jwt'))
  @Get()
  getProfile(@Request() req) {
    return req.user;
  }
}

这样,你已经设置了一个基础的 JWT 鉴权系统。 请注意,密钥应存储在环境变量中,并且不要在生产中硬编码。

此外,确保根据你的应用需求修改用户验证逻辑(例如从数据库中查询用户)。

相关文章

  • nestjs 使用nodemailer 编写邮件发送模块服务

    NestJS邮件发送指南:使用Nodemailer和@nestjs-modules/mailer。安装必要包,创建邮件模块和服务,配置SMTP,发送邮件。确保SMTP配置正确,使用环境变量保护敏感信息。

  • nestjs 配置swagger

    NestJS项目中使用Swagger生成API文档的详细指南,包括安装依赖、配置Swagger、设置基础信息、认证、生成文档、添加Swagger装饰器等步骤,以及如何访问和使用Swagger文档。