NestJS-检查失败时将用户从防护中重定向

时间:2018-12-20 13:48:08

标签: redirect nestjs

我已向正在构建的NestJS应用程序添加了一些简单且有效的登录功能。我现在想阻止已注销用户访问某些路由,因此我添加了一个简单的AuthGuard,看起来像这样;

@Injectable()
export class AuthGuard implements CanActivate {
    public canActivate(
        context: ExecutionContext,
    ): boolean {
        const request = context.switchToHttp().getRequest();
        const response = context.switchToHttp().getResponse();
        if (typeof request.session.authenticated !== "undefined" && request.session.authenticated === true) {
            return true;
        }
        return false;
    }
}

这可以阻止用户访问应用了防护的路由,但是这样做只是显示了此JSON响应;

{
    "statusCode": 403,
    "error": "Forbidden",
    "message": "Forbidden resource"
}

我想要的是当防护失败时将用户重定向到登录页面。我尝试将return false替换为response.redirect("/auth/login");,尽管它可以工作,但在控制台中却收到消息

(node:11526) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Can't set headers after they are sent.

(node:11526) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

因此,尽管它可以工作,但这似乎不是最佳解决方案。

警卫被召唤的路线如下:

@Get()
@UseGuards(AuthGuard)
@Render("index")
public index() {
    return {
        user: {},
    };
}

防护措施失败后,是否可以正确重定向用户?

2 个答案:

答案 0 :(得分:5)

您可以使用保护和过滤器来实现您想要的。通过来自守卫的未授权异常并处理从过滤器到重定向的异常。这是一个这样的过滤器:

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
} from '@nestjs/common';
import { Response } from 'express';
import { UnauthorizedException } from '@nestjs/common';

@Catch(UnauthorizedException)
export class ViewAuthFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const status = exception.getStatus();

    response.status(status).redirect('/admins');
  }
}

以下是它的使用方法:

@Get('/dashboard')
@UseGuards(JwtGuard)
@UseFilters(ViewAuthFilter)
@Render('dashboard/index')
dashboard() {
    return {};
}

答案 1 :(得分:0)

应该返回JSON的端点返回到HTML内容的重定向似乎很奇怪。

但是,如果要管理如何使用用户友好的自定义内容处理异常,我建议您看一下异常过滤器:

https://docs.nestjs.com/exception-filters

直接从nestjs文档中粘贴,这是一个明确的示例:

 class AnimalBox[A <: Animal]
 val animalBox = new AnimalBox[Animal] // compiles
 val dogBox = new AnimalBox[Dog] // compiles: Dog is a subclass of Animal
 val catBox = new AnimalBox[Cat] // compiles: Cat is a subclass of Animal
 val badBox = new AnimalBox[Any] // does not compile: Any is not a subclass

 animalBox.set(new Dog) // compiles: Dog is an Animal
 animalBox.set(new Cat) // compiles: Cat is an Animal
 animalBox.set(new Pear) // does not compile: Pear is not an Animal

 dogBox.set(new Dog) // compiles
 dogBox.set(new Cat) // does not compile: cat is not a dog