【问题标题】:Using failureRedirect option of passport-local with Nest.js在 Nest.js 中使用本地护照的 failureRedirect 选项
【发布时间】:2022-08-04 21:21:07
【问题描述】:

我需要使用 Nest.js 进行身份验证后的处理帮助 在使用 Nest.js 进行身份验证时,我是否通过本地护照的 failureRedirect 选项?

没有 Nest.js

app.post(\'/login\', passport.authenticate(\'local\', {
    //Passing options here.
    successRedirect: \'/\',
    failureRedirect: \'/login\'
}));

我的代码是。 (使用 Nest.js)

本地策略.ts

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

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
    constructor(private authService: AuthService) {
        super({
            //I tried passing the option here. but failed.
        })
    }

    async validate(username: string, password: string): Promise<string | null> {
        const user = this.authService.validate(username, password);
        if (!user) {
            throw new UnauthorizedException();
        }
        return user;
    }
}

local.guard.ts

import { Injectable } from \"@nestjs/common\";
import { AuthGuard } from \"@nestjs/passport\";

@Injectable
export class LocalAuthGuard extends AuthGuard(\'local\') {}

身份验证控制器.ts

import { Controller, Get, Post, Render, UseGuards } from \"@nestjs/common\";
import { LocalAuthGuard } from \"./local.guard\";

@Controller()
export class AuthController {
    @Get(\"/login\")
    @Render(\"login\")
    getLogin() {}
    
    //Redirect to \'/login\' when authentication failed.
    @UseGuards(LocalAuthGuard)
    @Post(\"/login\")
    postLogin() {}
}

auth.module.ts

import { Module } from \"@nestjs/common\";
import { PassportModule } from \"@nestjs/passport\";
import { AuthController } from \"./auth.controller\";
import { AuthService } from \"./auth.service\";
import { LocalStrategy } from \"./local.strategy\";
import { LocalAuthGuard } from \"./local.guard\";

@Module({
   controllers: [AuthController],
   imports: [PassportModule],
   providers: [AuthService, LocalStrategy, LocalAuthGuard]
})
export class AuthModule {}

我尝试将代码添加到AuthController#postLogin 以在登录失败时重定向,但代码似乎只在成功登录时运行。 如果使用passport-local的failureRedirect选项登录失败,我想再次重定向到登录页面。

    标签: node.js nestjs passport.js passport-local nestjs-passport


    【解决方案1】:

    我找到了一种解决方法,因为遗憾的是使用护照选项不起作用:

    @Injectable()
    export class LocalAuthGuard extends AuthGuard('local') {
      getAuthenticateOptions(context: ExecutionContext): IAuthModuleOptions {
        return {
          successReturnToOrRedirect: '/',
          failureRedirect: '/login',
        };
      }
    }
    

    相反,我创建了一个 Nestjs 过滤器来捕获包含重定向 URL 的异常。

    重定向.exception.ts

    export class RedirectingException {
      constructor(public url: string) {}
    }
    

    重定向异常.filter.ts

    import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common';
    import { Response } from 'express';
    import { RedirectingException } from './redirecting.exception';
    
    @Catch(RedirectingException)
    export class RedirectingExceptionFilter implements ExceptionFilter {
      catch(exception: RedirectingException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();
        response.redirect(exception.url);
      }
    }
    

    在我的验证方法中,我使用正确的错误消息抛出 RedirectingException,例如

    throw new RedirectingException('/login?error="User not found"');
    

    控制器处理其余的重定向并将错误传递给视图,因此可以显示:

    @Get('/login')
    @Render('login.pug')
    @Public()
    async login(@Query() query) {
      return { error: query.error };
    }
    
    @Post('/login')
    @Public()
    @UseGuards(LocalAuthGuard)
    @Redirect('/')
    async doLogin() {}
    

    我宁愿使用包括 failureFlash 在内的护照功能,但我无法让它工作。

    【讨论】:

      猜你喜欢
      • 2021-09-11
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 2019-05-23
      • 2019-06-23
      • 1970-01-01
      • 2013-12-12
      • 2019-04-25
      相关资源
      最近更新 更多