На этом уроке мы узнаем, как реализовать аутентификацию и авторизацию в приложении NestJS с использованием Passport и JWT.

- Установите необходимые пакеты: Установите необходимые пакеты для Passport, JWT и хеширования паролей:
npm install --save @nestjs/passport @nestjs/jwt passport passport-jwt bcryptjs
- Создайте сущность пользователя: создайте новый файл с именем
user.entity.tsв папкеsrcи добавьте следующий код:
import { Entity, PrimaryGeneratedColumn, Column, Unique } from 'typeorm';
@Entity()
@Unique(['username'])
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
}
- Создайте UserService: создайте новый файл с именем
user.service.tsвнутри папкиsrcи добавьте следующий код:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
import * as bcrypt from 'bcryptjs';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}
async createUser(username: string, password: string): Promise<User> {
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = this.userRepository.create({
username,
password: hashedPassword,
});
return this.userRepository.save(newUser);
}
}
- Создайте AuthModule: создайте новый файл с именем
auth.module.tsвнутри папкиsrcи добавьте следующий код:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserService } from './user.service';
import { User } from './user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
providers: [UserService],
})
export class AuthModule {}
- Обновите AppModule: импортируйте
AuthModuleв файлapp.module.ts:
import { AuthModule } from './auth.module';
@Module({
imports: [
AuthModule,
// ...
],
providers: [AppResolver, AppService],
})
export class AppModule {}
- Создайте JwtStrategy: создайте новый файл с именем
jwt.strategy.tsвнутри папкиsrcи добавьте следующий код:
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UserService } from './user.service';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private userService: UserService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: '<your_jwt_secret>',
});
}
async validate(payload: any) {
const user = await this.userService.findOne(payload.username);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
Обязательно замените <your_jwt_secret> своим собственным секретом JWT.
- Создайте AuthService: создайте новый файл с именем
auth.service.tsв папкеsrcи добавьте следующий код:
import { Injectable } from '@nestjs/common';
import { UserService } from './user.service';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcryptjs';
@Injectable()
export class AuthService
{
constructor( private userService: UserService, private jwtService: JwtService, ) {}
async validateUser(username: string, password: string): Promise<any> {
const user = await this.userService.findOne(username);
if (user && (await bcrypt.compare(password, user.password))) {
return user;
}
return null;
}
async login(user: any) {
const payload = {
username: user.username, sub: user.userId
};
return { access_token: this.jwtService.sign(payload), };
}
}
- Обновите AuthModule: обновите файл
auth.module.ts, включив в него новый AuthService и JwtStrategy:
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { UserService } from './user.service';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { User } from './user.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forFeature([User]),
PassportModule,
JwtModule.register({
secret: '<your_jwt_secret>',
signOptions: { expiresIn: '1h' },
}),
],
providers: [UserService, AuthService, JwtStrategy],
})
export class AuthModule {}
Обязательно замените <your_jwt_secret> своим собственным секретом JWT.
- Защита маршрутов GraphQL: обновите файл
app.module.ts, включив в него конфигурациюGraphQLModule.forRoot(), и используйте параметрcontext, чтобы добавить пользователя в контекст GraphQL:
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { AuthModule } from './auth.module';
// ...
@Module({
imports: [
AuthModule,
// ...
GraphQLModule.forRoot({
autoSchemaFile: 'schema.gql',
context: ({ req }) => ({ user: req.user }),
}),
],
// ...
})
export class AppModule {}
- AuthGuard: теперь вы можете защитить любой преобразователь GraphQL с помощью декоратора
@UseGuards():
import { UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Query('protectedData')
@UseGuards(AuthGuard('jwt'))
async getProtectedData(@Context('user') user: User) {
// Your protected data logic here
}
Теперь вы реализовали аутентификацию и авторизацию с помощью Passport и JWT в своем приложении NestJS. Вы можете использовать это как отправную точку для дальнейшей настройки и расширения функций безопасности вашего приложения.