如何在 Nestjs 中获取用户信息?

Posted

技术标签:

【中文标题】如何在 Nestjs 中获取用户信息?【英文标题】:How to get user's information in Nest.js? 【发布时间】:2020-01-15 05:16:14 【问题描述】:

我正在使用 Angular+Nest 开发一个网站。我创建了一个服务(Angular),以便客户端可以在项目启动时从服务器获取用户信息(与新鲜相同)。有些动作不需要登录,所以登录是可选的。

我想要的是如果用户已经登录,那么客户端应该发送一个请求来获取用户的信息。

服务器代码如下:

export const RequestUser = createParamDecorator((data, req): RequestUserDTO => 
    return req.user;
);

@Controller('auth')
export class AuthController 
  @Get('getUserInfoByToken')
  async getUserInfoByToken(@RequestUser() user: User): Promise<any> 
    if (user) 
      return 
        nickname: user.nickname,
        level: user.level
      ;
    
  

但是,如果我不添加 @UseGuards(AuthGuard()) 作为装饰器,我发现没有任何回报。但是如果我添加它,当项目启动时,这个请求会返回401 作为状态码。然后网页会转到登录页面。

我应该怎么做才能避免这种情况?并非每个操作都需要登录。

【问题讨论】:

【参考方案1】:

如果您想到了完全不同的方法,请告诉我 - 我们会尽力提供帮助。

将尝试提供更详细的示例,其中包括后台passport。它假定使用了passport 并且正在发送Authorization 令牌。

const RegisteredPassportModule = PassportModule.register( defaultStrategy: 'bearer' )HttpStrategy 添加到一些AuthModulePassportModule.register( defaultStrategy: 'bearer' ) 添加到导入到AuthModule

然后:

AuthService 是一项服务(也是AuthModule 的一部分),它允许通过通过Authorization 标头传递的令牌发送的令牌直接从数据库中查找给定用户。

import  Strategy  from 'passport-http-bearer';
import  PassportStrategy  from '@nestjs/passport';
import  Injectable, UnauthorizedException  from '@nestjs/common';
import  AuthService  from './auth.service';

@Injectable()
export class HttpStrategy extends PassportStrategy(Strategy) 
  constructor(private readonly authService: AuthService) 
    super()
  

  async validate(token: string) 
    const user = await this.authService.findUserByToken(token);
    if (!user) 
      throw new UnauthorizedException();
    
    return user;
  


使用毕竟很简单(你可以为控制器的任何一种方法设置守卫):

@UseGuards(AuthGuard())
@Get()
someMethod(@Req() request: RequestWithUser, ...) 
  // ...


RequestWithUser 只是:

import  User as UserEntity  from '../../models/user.entity'

export type RequestWithUser = Request &  user: UserEntity 

/user 端点只会返回request.user

我希望这会有所帮助!

【讨论】:

如果我想获取用户信息,我必须添加@UseGuards(AuthGuard())。但有时用户不需要登录。但是,客户端仍然发送带有令牌的请求以获取用户的信息。并且服务器会返回 401。web 收到这个状态码会转到登录页面。但这不是我想要的。 我的意思是,如果令牌有效,该服务器如何返回用户信息。否则,返回 null 或其他状态码为 200 这很奇怪。如果您未登录,则无法访问your profile 或任何其他user profile 的资源,因此需要选择 401。见this。请认真考虑前端不应该查询该数据 - 正确使用 API 是它的工作。 该服务的目标是在项目启动时获取用户信息。例如,当用户刷新页面时,每个数据都是清晰的。在 localstorage 中只设置了令牌。但是 idk 令牌是否有效。因此,每次刷新页面时,都会发送请求。【参考方案2】:

如果你真的坚持这种方式(见cmets),可以使用Interceptors:


@Injectable()
export class GetUserInterceptor implements NestInterceptor 
  constructor(private readonly authService: AuthService) 
  

  async intercept(context: ExecutionContext, next: CallHandler) 
    const request = context.switchToHttp().getRequest()
    const item = await this.authService.getByToken(/* extract me from headers*/)
    request.user = item
    return next.handle()
  


所以不需要 AuthGuard。

【讨论】:

【参考方案3】:

在 AuthGuard 中编写条件逻辑来检查请求中是否提供了用户。

【讨论】:

以上是关于如何在 Nestjs 中获取用户信息?的主要内容,如果未能解决你的问题,请参考以下文章

NestJS:如何在从 JWT AuthGuard 扩展的 GraphQL 自定义 Guard 中从请求中获取用户

如何在 NestJS 控制器处理程序的请求中获取“已验证的正文”和“已验证的用户”?

如何在nestjs graphql中实现用户保护

NestJS - 避免返回用户密码

有啥方法可以访问 NestJS 守卫中处理程序方法的参数?

NestJs - 无法在 RolesGuard 中获取用户上下文