Hen*_*mos 5 node.js typescript passport-local passport.js nestjs
我在 NestJs 中有这段代码,下面有以下文件,但现在它说“未知的身份验证策略“本地””,我已经寻找解决方案,它们都指向导入错误,但我已将 localstrategy 导入到 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=true&w=majority',
),
ThrottlerModule.forRoot({
ttl: 60,
limit: 10,
}),
AuthModule,
UsersModule,
],
controllers: [AppController],
providers: [AppService, LocalStrategy],
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
auth.module.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 {}
Run Code Online (Sandbox Code Playgroud)
本地策略.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();
}
return user;
}
}
Run Code Online (Sandbox Code Playgroud)
应用程序控制器.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;
}
}
Run Code Online (Sandbox Code Playgroud)
本地认证.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
Run Code Online (Sandbox Code Playgroud)
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): Promise<UserDocument | any> {
const user = await this.usersService.findOne(email);
if (user && (await user.compareHash(pass))) {
const { password, ...result } = user.toObject();
await this.usersService.updateLastLogin(user._id);
return result;
}
return null;
}
async login(user: UserDocument): Promise<string> {
const payload = { email: user.email, sub: user._id, roles: user.roles };
return this.jwtService.sign(payload);
}
}
Run Code Online (Sandbox Code Playgroud)
jwt-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
Run Code Online (Sandbox Code Playgroud)
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 && 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 };
}
}
Run Code Online (Sandbox Code Playgroud)
stackoverflow上没有类似的问题解决了我的问题,有人知道它是什么吗?
最近,由于我对文件夹的组织似乎找不到文件,我最终遇到了此错误,local.strategy并且jwt.strategy在每个 Guard 中我必须添加一个导入策略的构造函数。
目前你的代码是这样的:
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
Run Code Online (Sandbox Code Playgroud)
通过添加如下结构来更改文件:
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {
constructor(private readonly localStrategy: LocalStrategy) {
super();
}
}
Run Code Online (Sandbox Code Playgroud)
如果这不起作用,则此错误的真正原因与作用域请求注入有关,显然中间件必须忽略中间件的执行LocalAuthGuard。例如:多租户连接,如果您从请求中获取数据库的名称,最终可能会忽略 LocalAuthGuard 的执行,因为在文件中local.strategy.ts您正在使用构造函数private authService: AuthService,并且如果它确实正在建立多租户连接,请检查如何进行您正在将存储库注入名为UsersService.
希望这可以帮助任何寻找此错误的人。