gengminy
갱미니의 코딩일지
gengminy
전체 방문자
오늘
어제
  • 분류 전체보기 (61)
    • 🚀 프로젝트 (16)
      • 🎸 고스락 티켓 (4)
      • 🌞 내친소 (5)
      • 🥁 두둥 (7)
    • 📡 백엔드 (31)
      • 🌱 Spring Boot (13)
      • 🐱 Nest.js (10)
      • ⭐ Node.js (8)
    • 🏭 Infra (11)
      • ⚙ 준비를 위한 준비 (2)
      • 🥑 AWS (3)
      • 🐳 Docker (3)
      • ⚡ Github Actions (3)
    • 🌊 프론트엔드 (1)
      • 🌌 React.js (1)
    • 😎 주저리 (2)

블로그 메뉴

  • 💻Github
  • 📸Instagram
  • ✨Blog

공지사항

인기 글

태그

  • nestjs
  • 네스트
  • springboot
  • JSON
  • docker
  • 슬랙알림
  • JWT
  • GithubActions
  • 깃헙액션
  • Spring
  • oauth2
  • 도커
  • SlackAPI
  • 스프링
  • AWS
  • 스프링부트
  • OAuth
  • github
  • nodejs
  • nest

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
gengminy
📡 백엔드/🐱 Nest.js

[NestJs] 따라하면서 배우는 NestJs - 8 (권한 부여, 유저와 게시글 관계 부여)

[NestJs] 따라하면서 배우는 NestJs - 8 (권한 부여, 유저와 게시글 관계 부여)
📡 백엔드/🐱 Nest.js

[NestJs] 따라하면서 배우는 NestJs - 8 (권한 부여, 유저와 게시글 관계 부여)

2022. 7. 9. 13:43

✅ 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 추가

 

 

JWT 없이 GET 요청을 보내면 권한 없음 오류 발생

 

 

Signin 으로 얻은 JWT을 request 에 실어보내면 권한을 정상적으로 얻는다

 

 

권한 처리도 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
    '📡 백엔드/🐱 Nest.js' 카테고리의 다른 글
    • [NestJs] 따라하면서 배우는 NestJs - 9 (로그, 설정)
    • [NestJs] 따라하면서 배우는 NestJs - 7 (JWT, passport 이용한 인증 구현)
    • [NestJs] 따라하면서 배우는 NestJs - 6 (auth 모듈 구현)
    • [NestJs] 따라하면서 배우는 NestJs - 5 (레포지토리 구현 및 DB 이용 CRUD)
    gengminy
    gengminy
    코딩

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.