@Speakermen

Нужен ли LocalAuthGuard при регистрации?

Не знаю нужен ли @UseGuards(LocalAuthGuard) для регистрации если использую то вся логика крашится валидацию в dto ещё не добавил

Login
Если email и password верны возвращается access_token
Если email верный а password не верный возвращается 401 Email or password is incorrect Unauthorized
Если email не верный а password верный возвращается 401 Email or password is incorrect Unauthorized

Register
Если email существует 409 Choose another email Conflict
Если не существует создать пользователя и вернуть access_token

Если использую
@UseGuards(LocalAuthGuard)
  @Post('/register')

Вся логика крашится так как в local.strategy.ts проверить на существование email-a не могу так как при login-e будет что такой email уже существует

Как я понял в access_token нужно хранить только user_id и role
А в refresh token пока не знаю

@UseGuards(LocalAuthGuard)
  @Post('/login')
  async login(@ReqUser() reqUser) {
    return this.authService.login(reqUser);
  }


import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from '../auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super({ usernameField: 'email' });
  }

  async validate(email: string, password: string): Promise<any> {
    const user = await this.authService.validateUser({ email, password });

    if (!user) {
      throw new UnauthorizedException('Email or password is incorrect');
    }

    await this.authService.validatePassport(password, user.password);

    return user;
  }
}


public async login(user): Promise<any> {
    return {
      access_token: this.jwtService.sign({
        username: user.username,
        sub: user.id,
      }),
    };
  }


При регистрации мне же не нужен в controller @UseGuards(LocalAuthGuard)

Весь код

//auth.controller.ts
import { ReqBody } from './decorators/reqbody.decorator';
import {
  Body,
  Controller,
  Get,
  Post,
  UseGuards,
  ValidationPipe,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { CreateRegisterDto } from './dto/create-register.dto';
import { ReqUser } from './decorators/requser.decorator';
import { JwtAuthGuard } from './guards/jwt-auth.guard';
import { LocalAuthGuard } from './guards/local-auth.guard';

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

  @UseGuards(LocalAuthGuard)
  @Post('/login')
  async login(@ReqUser() reqUser) {
    return this.authService.login(reqUser);
  }

  /*
  @UseGuards(LocalAuthGuard)
  @Post('/register')
  async register(
    @ReqBody(new ValidationPipe({ validateCustomDecorators: true }))
    createRegisterDto: CreateRegisterDto,
  ) {
    return this.authService.register(createRegisterDto);
  }
  */

  @Post('/register')
  async register(@Body() createRegisterDto: CreateRegisterDto) {
    return this.authService.register(createRegisterDto);
  }

  @UseGuards(JwtAuthGuard)
  @Get('/profile')
  async profile(@ReqUser() reqUser) {
    return reqUser;
  }
}

//local.strategy.ts
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from '../auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super({ usernameField: 'email' });
  }

  async validate(email: string, password: string): Promise<any> {
    const user = await this.authService.validateUser({ email, password });

    if (!user) {
      throw new UnauthorizedException('Email or password is incorrect');
    }

    await this.authService.validatePassport(password, user.password);

    return user;
  }
}

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

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: process.env.JWT_SECRET,
    });
  }

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

//auth.service.ts
import { CreateLoginDto } from './dto/create-login.dto';
import { CreateRegisterDto } from './dto/create-register.dto';
import { UsersService } from './../users/users.service';
import {
  ConflictException,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { User as UserModel } from '@prisma/client';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';

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

  public async validateUser(createLoginDto: CreateLoginDto): Promise<any> {
    return await this.usersService.findOne({
      email: createLoginDto.email,
    });
  }

  public async validateEmail(email: string, inputEmail: string) {
    if (email === inputEmail) {
      throw new ConflictException('Choose another email');
    }
  }

  public async validatePassport(password: string, hash: string) {
    if (!(await bcrypt.compare(password, hash))) {
      throw new UnauthorizedException('Email or password is incorrect');
    }
  }

  public async login(user): Promise<any> {
    return {
      access_token: this.jwtService.sign({
        username: user.username,
        sub: user.id,
      }),
    };
  }

  public async register(createRegisterDto: CreateRegisterDto): Promise<any> {
    const user = await this.validateUser(createRegisterDto);

    if (user) {
      await this.validateEmail(user.email, createRegisterDto.email);
    }

    createRegisterDto.password = await bcrypt.hash(
      createRegisterDto.password,
      12,
    );

    const payload = await this.usersService.create(createRegisterDto);

    return {
      access_token: this.jwtService.sign({
        username: payload.username,
        sub: payload.id,
      }),
    };
  }
}
  • Вопрос задан
  • 182 просмотра
Решения вопроса 1
lssssssssssl
@lssssssssssl
Локальная стратегия нужна только при аутентификации(Можно и без неё обойтись, написав ручками то же самое).
В остальных случаях jwt стратегия.
Регистрация не должна иметь guard, ежели пользователя ещё нет в бд и проверять его не на что.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы