【问题标题】:How to get user's information in Nest.js?如何在 Nestjs 中获取用户信息?
【发布时间】: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 作为状态码。然后网页会转到登录页面。

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

【问题讨论】:

    标签: angular nestjs


    【解决方案1】:

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

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

    • const RegisteredPassportModule = PassportModule.register({ defaultStrategy: 'bearer' })
    • HttpStrategy 添加到一些AuthModule
    • PassportModule.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 中编写条件逻辑来检查请求中是否提供了用户。

      【讨论】:

        猜你喜欢
        • 2019-05-08
        • 2020-12-25
        • 2020-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-10
        • 2019-09-12
        • 2017-12-30
        相关资源
        最近更新 更多