首页 > 解决方案 > 如何使用 NestJS 完成 HTTP 基本身份验证

问题描述

我想知道如何使用常见的 NestJS 身份验证实践来完成 HTTP 基本身份验证。

例如,如果我使用这样的 AuthGuard,我会收到错误消息

(node:336) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { compareSync } from 'bcrypt';
import { User } from 'src/user/user.entity';
import { Repository } from 'typeorm';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    @InjectRepository(User) private readonly userRepository: Repository<User>,
  ) {}
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const b64auth = (request.headers.authorization || '').split(' ')[1] || '';
    const [username, password] = Buffer.from(b64auth, 'base64')
      .toString()
      .split(':');

    const user = await this.userRepository.findOne({
      where: { username },
    });
    if (user && compareSync(password, user.password) !== false) {
      request.user = user;
      return true;
    }
    const response = context.switchToHttp().getResponse();
    response.set('WWW-Authenticate', 'Basic realm="Authentication required."'); // change this
    response.status(401).send();
    return false;
  }
}

我怀疑,返回 false (并让 Nest 处理响应)不会“手动”将响应状态代码设置为 401 并发送响应。

如何使用这种古老的 http 授权机制保护某些路由?

标签: node.jsauthenticationnestjs

解决方案


我建议实现一个ExceptionFilter专门监听警卫抛出的异常的函数(UnauthorizedException)。然后,在过滤器中,根据需要设置响应,这样守卫就不会尝试发送多个响应,您可以根据需要设置响应。


推荐阅读