#node.js #typescript #passport.js #nestjs #passport-local
#node.js #машинописный текст #passport.js #гнездышко #паспорт-местный
Вопрос:
У меня есть этот код в NestJS со следующими файлами ниже, но теперь в нем написано «Неизвестная стратегия аутентификации «локальная»», я уже искал решения, и все они указывают на ошибку импорта, но у меня есть локальная стратегия, импортированная в auth.module и app.module (я уже протестировал ее удаление из app.module, но это ничего не меняет).
приложение.модуль.ts
import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { ThrottlerModule } from '@nestjs/throttler'; import { MongooseModule } from '@nestjs/mongoose'; import { AuthModule } from './auth/auth.module'; import { UsersModule } from './users/users.module'; import { LocalStrategy } from './auth/local.strategy'; @Module({ imports: [ MongooseModule.forRoot( 'mongodb srv://user:password@db.db.mongodb.net/db?retryWrites=trueamp;w=majority', ), ThrottlerModule.forRoot({ ttl: 60, limit: 10, }), AuthModule, UsersModule, ], controllers: [AppController], providers: [AppService, LocalStrategy], }) export class AppModule {}
auth.модуль.ts
import { Module } from '@nestjs/common'; import { AuthService } from './auth.service'; import { UsersModule } from '../users/users.module'; import { PassportModule } from '@nestjs/passport'; import { LocalStrategy } from './local.strategy'; import { JwtModule } from '@nestjs/jwt'; import { JwtStrategy } from './jwt.strategy'; import 'dotenv/config'; @Module({ imports: [ UsersModule, PassportModule, JwtModule.register({ secret: process.env.JWTSECRET, signOptions: { expiresIn: '60s' }, }), ], providers: [AuthService, LocalStrategy, JwtStrategy], exports: [AuthService], }) export class AuthModule {}
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): Promiselt;anygt; { const user = await this.authService.validateUser(email, password); if (!user) { throw new UnauthorizedException(); } return user; } }
app.controller.ts
import { Controller, Request, Post, UseGuards, Res, Get, Body, } from '@nestjs/common'; import { AuthService } from './auth/auth.service'; import { MakeAuthDto } from './auth/dto/make-auth.dto'; import { JwtAuthGuard } from './auth/jwt-auth.guard'; import { LocalAuthGuard } from './auth/local-auth.guard'; import { Roles } from './utils/decorators/roles.decorator'; import { Role } from './utils/enums/role.enum'; import { RolesGuard } from './utils/guards/roles.guard'; @Controller() export class AppController { constructor(private authService: AuthService) {} @UseGuards(LocalAuthGuard) @Post('auth/login') async login( @Body() _: MakeAuthDto, @Request() req, @Res({ passthrough: true }) res, ) { console.log(req.user); const access_token = await this.authService.login(req.user); res.cookie('jwt', access_token); return req.user; } @UseGuards(JwtAuthGuard, RolesGuard) @Roles(Role.Admin) @Get('tests') getProfile(@Request() req) { return req.user; } }
local-auth.guard.ts
import { Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class LocalAuthGuard extends AuthGuard('local') {}
auth.service.ts
import { Injectable } from '@nestjs/common'; import { UsersService } from 'src/users/users.service'; import { JwtService } from '@nestjs/jwt'; import { UserDocument } from 'src/users/entities/user.entity'; @Injectable() export class AuthService { constructor( private usersService: UsersService, private jwtService: JwtService, ) {} async validateUser(email: string, pass: string): Promiselt;UserDocument | anygt; { const user = await this.usersService.findOne(email); if (user amp;amp; (await user.compareHash(pass))) { const { password, ...result } = user.toObject(); await this.usersService.updateLastLogin(user._id); return result; } return null; } async login(user: UserDocument): Promiselt;stringgt; { const payload = { email: user.email, sub: user._id, roles: user.roles }; return this.jwtService.sign(payload); } }
jwt-auth.guard.ts
import { Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') {}
jwt.strategy.ts
import { ExtractJwt, Strategy } from 'passport-jwt'; import { PassportStrategy } from '@nestjs/passport'; import { Injectable } from '@nestjs/common'; import 'dotenv/config'; const cookieExtractor = function (req) { let token = null; if (req amp;amp; req.cookies) { token = req.cookies['jwt']; } return token; }; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor() { super({ jwtFromRequest: ExtractJwt.fromExtractors([cookieExtractor]), ignoreExpiration: false, secretOrKey: process.env.JWTSECRET, }); } async validate(payload: any) { return { userId: payload.sub, email: payload.email, roles: payload.roles }; } }
Ни один подобный вопрос о stackoverflow не решил мою проблему, кто-нибудь знает, что это может быть?
Комментарии:
1. Не уверен, что это технически проблема, но с новейшей версией passport
0.5.0
вам нужно позвонитьpassport.initialize()
, например,app.use(passport.initialize())
для приложения на основе express. Интересно, может ли это каким-то образом быть причиной.2. @AlexanderStaroselsky Куда мне нужно это поместить?
3. Ну, в стандартном экспресс-приложении это было бы просто что-то вроде этого в главном файле app.js . Вы можете попробовать просто выполнить
use
инструкцию в своемmain.ts
(файле инициализации) или аналогичном.import * as passport from 'passport'; //.. app.use(passport.initialize());
4. Область действия вашего
UsersService
запроса ограничена?