✅ Boards 모듈에서 AuthGuard 사용하기
📝./src/boards/boards.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthModule } from 'src/auth/auth.module';
import { BoardRepository } from './board.repository';
import { BoardsController } from './boards.controller';
import { BoardsService } from './boards.service';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forFeature([BoardRepository]),
AuthModule,
],
controllers: [BoardsController],
providers: [BoardsService],
})
export class BoardsModule {}
📝./src/boards/boards.controller.ts
@Controller('boards')
@UseGuards(AuthGuard())
export class BoardsController {
...
}
컨트롤러 레벨에 UseGuards 추가
권한 처리도 Guard 관련 코드 몇개만 뚝딱 했는데 되니까 상당히 편하다
✅ User와 Board 사이의 관계 정의
📝./src/auth/user.entity.ts
@Entity()
@Unique(['username'])
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
@OneToMany((type) => Board, (board) => board.user, { eager: true })
boards: Board[];
async validatePassword(password: string): Promise<boolean> {
const isValid = await bcrypt.compare(password, this.password);
return isValid;
}
}
📝./src/boards/board.entity.ts
@Entity()
export class Board extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
description: string;
@Column()
status: BoardStatus;
@ManyToOne((type) => User, (user) => user.boards, { eager: false })
user: User;
}
관계 정의를 위해 각 엔티티 정의에 들어가서 관계를 지정해주면 된다
여기서는 User 가 Board 에 대해서 OneToMany 의 관계이고
반대로는 ManyToOne 의 관계이다
eager 옵션을 한쪽은 true, 한쪽은 false로 주었는데
강의에선 설명하지 않았지만 순환 참조 막을라고 넣은 것 같다
✅ 게시글 생성할 때 유저 정보 전달
📝./src/boards/boards.controller.ts
@Post()
@UsePipes(ValidationPipe)
createBoard(
@Body() createBoardDto: CreateBoardDto,
@GetUser() user: User,
): Promise<Board> {
return this.boardsService.createBoard(createBoardDto, user);
}
📝./src/boards/boards.service.ts
createBoard(createBoardDto: CreateBoardDto, user: User): Promise<Board> {
return this.boardRepository.createBoard(createBoardDto, user);
}
📝./src/boards/board.repository.ts
@EntityRepository(Board)
export class BoardRepository extends Repository<Board> {
async createBoard(
createBoardDto: CreateBoardDto,
user: User,
): Promise<Board> {
const { title, description } = createBoardDto;
const board = this.create({
title,
description,
status: BoardStatus.PUBLIC,
user,
});
await this.save(board);
return board;
}
}
인자로 User 전달을 추가해준다
@GetUser 은 저번 시간에 만들었던 커스텀 데코레이터
req.user 를 즉시 가져오게 하는 데코레이터다
board 엔티티에 user 정보를 정의해놓았기 때문에 바로 인자 전달해서 생성하면 된다
✅ 특정 유저의 게시글만 가져오기
📝./src/boards/boards.controller.ts
@Get()
getAllBoard(@GetUser() user: User): Promise<Board[]> {
return this.boardsService.getAllBoards(user);
}
📝./src/boards/boards.service.ts
async getAllBoards(user: User): Promise<Board[]> {
const query = this.boardRepository.createQueryBuilder('board');
query.where('board.userId = :userId', { userId: user.id });
const boards = await query.getMany();
return boards;
}
이번 예제에서는 repository API 대신에 queryBuilder를 사용했다
복잡한 SQL 쿼리를 조작할 수 있도록 TypeORM 에서 제공해준다
getMany 는 해당하는 결과를 전부 가져오는 메소드다
✅ 자신이 생성한 게시글 지우기
📝./src/boards/boards.controller.ts
@Delete('/:id')
deleteBoard(
@Param('id', ParseIntPipe) id: number,
@GetUser() user: User,
): Promise<void> {
return this.boardsService.deleteBoard(id, user);
}
📝./src/boards/boards.service.ts
async deleteBoard(id: number, user: User): Promise<void> {
const result = await this.boardRepository.delete({ id, user });
if (result.affected === 0) {
throw new NotFoundException(`Can't find Board with id ${id}`);
}
}
인자로 user 정보까지 전달해주면
권한이 있는 user만 그 게시글을 지울 수 있게 된다
'📡 백엔드 > 🐱 Nest.js' 카테고리의 다른 글
[NestJs] 따라하면서 배우는 NestJs - 9 (로그, 설정) (0) | 2022.07.09 |
---|---|
[NestJs] 따라하면서 배우는 NestJs - 7 (JWT, passport 이용한 인증 구현) (0) | 2022.07.08 |
[NestJs] 따라하면서 배우는 NestJs - 6 (auth 모듈 구현) (0) | 2022.07.07 |
[NestJs] 따라하면서 배우는 NestJs - 5 (레포지토리 구현 및 DB 이용 CRUD) (0) | 2022.07.07 |
[NestJs] TypeORM 사용 시 RepositoryNotFoundError 해결하기 (0) | 2022.07.06 |