护照是Node.js的流行身份验证中间件,提供了各种身份验证策略,包括JWT(JSON Web令牌)身份验证。 Nestjs是一个有力的框架,用于构建具有打字稿的可扩展和可维护的服务器端应用程序。在本文中,我们将探讨如何在Nestjs应用程序中使用Passport实施JWT身份验证。
先决条件
我们开始之前,请确保您安装了以下先决条件:
-
node.js和npm
-
Nest Cli
-
mongodb p> li>
设置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测试工具等工具来测试身份验证端点。这是您可以使用卷发测试端点的方法:
-
注册新用户:
curl -x post http://localhost:3000/auth/register -h“ content -type:application/json” -d'{“ username”:“ tastuser”,“ password”:“ testpassword”}'}' -
使用注册用户登录:
curl -x post http://localhost:3000/auth/login -h“ content -type:application/json” -d'{“ username”:“ tastuser”,“ password”:“ testpassword”}'}' -
使用获得的令牌访问受保护的路线:
curl http://localhost:3000/profile -h“授权:承载者”
结论
在本文中,我们学会了如何使用Mongoose数据库中的Nestjs应用程序中的Passport实施JWT身份验证。我们介绍了设置杂种,创建用户架构,配置护照和JWT策略,并使用Authguard保护路线。这种方法提供了一种在Nestjs应用程序中处理用户身份验证和授权的安全有效方法。
这是一个示例项目存储库的链接,以更具体地演示本文中讨论的概念:Github Repo