Nestjs中的护照JWT身份验证
#node #jwt #nestjs #passportjs

Passport JWT Authentication in NestJS

护照是Node.js的流行身份验证中间件,提供了各种身份验证策略,包括JWT(JSON Web令牌)身份验证。 Nestjs是一个有力的框架,用于构建具有打字稿的可扩展和可维护的服务器端应用程序。在本文中,我们将探讨如何在Nestjs应用程序中使用Passport实施JWT身份验证。

先决条件

我们开始之前,请确保您安装了以下先决条件:

  1. node.js和npm

  2. Nest Cli

  3. mongodb

设置Nestjs项目

让我们从创建一个新的Nestjs项目开始。打开终端并运行以下命令:

nest new nest-jwt-auth-example

导航到项目目录:

cd nest-jwt-auth-example

安装依赖项

要使用Passport和Mongoose实现JWT身份验证,我们需要安装必要的软件包:

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

设置猫鼬

首先,让我们设置猫鼬以连接到您的mongoDB数据库。打开app.module.ts文件并配置mongoosemodule:

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://127.0.0.1:27017/nest-jwt-auth', {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

用您的MongoDB连接字符串替换连接URL。

创建用户模式

让我们使用猫鼬创建一个用户模式。在src目录中的一个名为用户的文件夹中创建一个名为user.schema.ts的新文件:

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { ObjectId } from 'mongodb';

@Schema()
export class User {
  @Prop({ required: true })
  username: string;

  @Prop({ required: true })
  password: string;
}

export type UserDocument = User & Document;

export const UserSchema = SchemaFactory.createForClass(User);

创建用户模块

现在,创建一个用户模块来管理与用户相关的操作。运行以下命令以生成新的模块,服务和控制器:

nest generate module user
nest generate service user
nest generate controller user

在user.service.ts文件中,实现用于用户注册的方法并获取用户:

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User, UserDocument } from './user.schema';

@Injectable()
export class UserService {
  constructor(@InjectModel(User.name) private userModel: Model<UserDocument>) {}

  async create(username: string, password: string): Promise<User> {
    const user = new this.userModel({ username, password });
    return user.save();
  }

  async findByUsername(username: string): Promise<User | null> {
    return this.userModel.findOne({ username }).exec();
  }

  async findById(id: string): Promise<User | null> {
    return this.userModel.findById(id).exec();
  }
}

设置护照和JWT策略

接下来,让我们配置护照并设置JWT策略。打开auth.module.ts文件并创建JWT策略:

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

@Module({
  imports: [
    PassportModule,
    JwtModule.register({
      secret: 'yourSecretKey', // Replace with your own secret key
      signOptions: { expiresIn: '1h' }, // Token expiration time
    }),
    UserModule,
  ],
  providers: [AuthService, JwtStrategy],
  exports: [JwtModule],
})
export class AuthModule {}

实施JWT策略

在身份文件夹中创建一个名为jwt.strategy.ts的文件,并实现JWT策略:

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { UserService } from '../user/user.service';
import { User } from '../user/user.schema';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private userService: UserService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'yourSecretKey', // Replace with your own secret key
    });
  }

  async validate(payload: any): Promise<User> {
    const user = await this.userService.findById(payload.sub);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

实施身份服务

在SRC目录内创建一个auth文件夹。在验证文件夹中,创建auth.service.ts:

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UserService } from '../user/user.service';
import { User } from '../user/user.schema';

@Injectable()
export class AuthService {
  constructor(
    private userService: UserService,
    private jwtService: JwtService,
  ) {}

  async validateUser(username: string, password: string): Promise<User | null> {
    const user = await this.userService.findByUsername(username);
    if (user && user.password === password) {
      return user;
    }
    return null;
  }

  async login(user: User): Promise<{ accessToken: string }> {
    const payload = { sub: user._id };
    return {
      accessToken: this.jwtService.sign(payload),
    };
  }
}

创建Auth Controller

通过运行以下命令来生成auth控制器:

nest generate controller auth

在auth.controller.ts文件中,实现身份验证端点:

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

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

  @Post('login')
  async login(@Request() req): Promise<any> {
    const user = req.user;
    const token = await this.authService.login(user);
    return { token };
  }

  @Post('register')
  async register(@Request() req): Promise<any> {
    const { username, password } = req.body;
    const user = await this.authService.register(username, password);
    return { user };
  }
}

使用Authguard保护路线

要使用JWT身份验证来保护路由,请使用Passport提供的验证。打开app.controller.ts文件并添加useguards装饰器:

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

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

测试端点

启动您的Nestjs应用程序:

npm run start

现在,您可以使用Curl,Postman或任何API测试工具等工具来测试身份验证端点。这是您可以使用卷发测试端点的方法:

  1. 注册新用户:
    curl -x post http://localhost:3000/auth/register -h“ content -type:application/json” -d'{“ username”:“ tastuser”,“ password”:“ testpassword”}'}'

  2. 使用注册用户登录:
    curl -x post http://localhost:3000/auth/login -h“ content -type:application/json” -d'{“ username”:“ tastuser”,“ password”:“ testpassword”}'}'

  3. 使用获得的令牌访问受保护的路线:
    curl http://localhost:3000/profile -h“授权:承载者”

结论

在本文中,我们学会了如何使用Mongoose数据库中的Nestjs应用程序中的Passport实施JWT身份验证。我们介绍了设置杂种,创建用户架构,配置护照和JWT策略,并使用Authguard保护路线。这种方法提供了一种在Nestjs应用程序中处理用户身份验证和授权的安全有效方法。

这是一个示例项目存储库的链接,以更具体地演示本文中讨论的概念:Github Repo