Сериализация: Как исключить столбцы сущностей в ответе json, но не внутренние запросы в Nestjs - PullRequest
0 голосов
/ 23 января 2019

Редактировать
Я посмотрел на этот вопрос / ответ Как исключить поле сущности из контроллера json
Но, как указано ниже - это исключает это поле из всех запросов (в той части, где при попытке обработки проверки пользователя поле пароля исключается с помощью запроса репозитория findOne для метода маршрута / контроллера, который не имеет ClassSerializerInterceptor

У меня есть сущность в nest.js / typeorm; Я пытаюсь исключить поле пароля из возвращенного json, но не исключаю поле пароля из любых запросов к репозиторию в моем сервисе. Например:

user.entity.ts:

import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, 
UpdateDateColumn, ManyToOne } from 'typeorm';
import { Exclude } from 'class-transformer';
import { Account } from '../accounts/account.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({
    unique: true,
  })
  email: string;

 @Column()
 password: string;
}

auth.controller.ts

import { Controller, Post, Body, Request, Req, Get, UseInterceptors, ClassSerializerInterceptor, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { IUserRequest } from '../../interfaces/user-request.interface';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Post('/login')
  async login(@Request() req: Request) {
    const user = await this.authService.checkCredentials(req.body);
    return this.authService.logUserIn(user.id);
  }

  @Get('/profile')
  @UseGuards(AuthGuard())
  @UseInterceptors(ClassSerializerInterceptor)
  async profile(@Request() req: IUserRequest) {
    const profile = await this.authService.getLoggedInProfile(req.user.id);
    return { profile };
  }
}

Если я добавлю Exclude() к паролю, вот так

@Exclude()
@Column()
password: string;

пароль включен в ответ

Если я удалю Column() из пароля,

@Exclude()
password: string;

Пароль исключен из ответа и всех внутренних запросов, таких как:

const user = await this.userRepository.findOne({ where: { id }, relations: ['account']});

Возможно ли это в nest.js, используя ClassSerializerInterceptor?

Если так, был бы признателен за указатель в правильном направлении.

1 Ответ

0 голосов
/ 24 января 2019

Вы можете пропустить свойства в зависимости от операции . В вашем случае вы бы использовали:

@Column()
@Exclude({ toPlainOnly: true })
password: string;

Это означает, что пароль пропускается только при преобразовании класса в json (при отправке ответа), а не при преобразовании json в класс (при получении запроса).

Затем добавьте @UseInterceptors(ClassSerializerInterceptor) в ваш контроллер или метод контроллера. Это автоматически преобразует класс сущности в json, когда вы его вернете.


Чтобы ClassSerializerInterceptor работал, убедитесь, что ваша сущность была сначала преобразована в класс. Это можно сделать автоматически, используя ValidationPipe с параметром { transform: true} или возвратом объекта из хранилища (базы данных). Также вы должны вернуть саму сущность:

@Post()
@UseInterceptors(ClassSerializerInterceptor)
addUser(@Body(new ValidationPipe({transform: true})) user: User) {
  // Logs user with password
  console.log(user);
  // Returns user as JSON without password
  return user;
  }

В противном случае вам придется преобразовать его вручную:

async profile(@Request() req: IUserRequest) {
  // Profile comes from the database so it will be an entity class instance already
  const profile = await this.authService.getLoggedInProfile(req.user.id);
  // Since we are not returning the entity directly, we have to transform it manually
  return { profile: plainToClass(profile) };
}
...