我在我正在构建的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
这样做的方式是阻止用户访问应用了守卫的路由,但这样做只会显示此 JSON 响应;
{
"statusCode": 403,
"error": "Forbidden",
"message": "Forbidden resource"
}
Run Code Online (Sandbox Code Playgroud)
我想要的是当守卫失败时用户被重定向到登录页面。我试过用return falsewith替换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: {},
};
}
Run Code Online (Sandbox Code Playgroud)
守卫失败后是否有可能正确重定向用户?
小智 7
您可以使用保护和过滤器来实现您想要的。通过来自守卫的未授权异常并处理从过滤器到重定向的异常。这是一个这样的过滤器:
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');
}
}
Run Code Online (Sandbox Code Playgroud)
下面是如何使用它:
@Get('/dashboard')
@UseGuards(JwtGuard)
@UseFilters(ViewAuthFilter)
@Render('dashboard/index')
dashboard() {
return {};
}
Run Code Online (Sandbox Code Playgroud)
应该返回 JSON 的端点却返回到 HTML 内容的重定向,这似乎很奇怪。
不过,如果您想使用用户友好的自定义内容来管理异常的处理方式,我建议您查看异常过滤器:
https://docs.nestjs.com/exception-filters
直接从nestjs的文档粘贴过来,这里是一个明确的例子:
import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';
import { HttpException } from '@nestjs/common';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const request = ctx.getRequest();
const status = exception.getStatus();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3937 次 |
| 最近记录: |