일정 관리 앱 서버 기능 추가하기 : 구현 전 이것 저것

이민호·2024년 6월 3일
0

Goal

회원가입, 로그인 기능이 있는 투두앱 백엔드 서버 만들기

ERD

수정된 ERD

API 명세서

1단계 : 일정과 댓글의 연관관계

설명

  • 지난 과제에서 만든 일정에 댓글을 추가할 수 있습니다.
  • ERD에도 댓글 모델을 추가합니다.
  • 각 일정에 댓글을 작성할 수 있도록 관련 클래스를 추가하고 연관 관계를 설정합니다.
  • 매핑 관계를 설정합니다. (1:1 or N:1 or N:M)

추가되는 entity : Comment

댓글필드데이터 유형
아이디(고유번호)bigint
댓글내용varchar
사용자 아이디varchar
일정 아이디bigint
작성일자timestamp
  • User

    • 하나의 user는 todo를 여러개 작성할 수 있으므로 OneToMany
    • 하나의 user는 comment를 여러개 작성 할 수 있으므로 OneToMany
  • todo

    • 여러개의 todo가 하나의 user에 의해 작성되므로 ManyToOne
    • 하나의 todo는 여러개의 comment를 가질 수 있으므로 OneToMany
  • comment

    • 여러개의 comment가 하나의 user에 의해 작성되므로 ManyToOne
    • 여러개의 comment가 하나의 todo에 의해 작성되므로 ManyToOne

수정되는 entity : User

사용자 필드데이터 유형
아이디(고유번호)bigint
별명varchar
사용자 이름varchar
비밀번호varchar
권한varchar
생성일timestamp

수정되는 entity : Todo

User 테이블이 생기면서 기존 Todo에 존재하는 password field가 중복된다고 판단.

일정 필드데이터 유형
아이디(고유번호)bigint
사용자 이름varchar
제목varchar
내용varchar
비밀번호varchar
생성일timestamp

2단계 : 댓글 등록

기능

  • 선택한 일정이 있다면 댓글을 등록합니다.

조건

  • 댓글이 등록되었다면 client에게 반환합니다.
  • 선택한 일정이 DB에 저장되어 있어야 합니다.
  • 댓글을 식별하는 고유번호, 댓글 내용, 댓글을 작성한 사용자 아이디, 댓글이 작성된 일정 아이디, 작성일자를 저장할 수 있습니다.

⚠️ 예외 처리

  • 선택한 일정의 ID를 입력 받지 않은 경우
CommentService.createComment
// todoRepository에서 id로 조회 및 예외처리
Todo todo = todoRepository.findById(dto.getTodo().getTodoId()).orElseThrow(()->
                 new NullPointerException("잘못된 접근입니다."));
  • 댓글 내용이 비어 있는 경우
CommentRequestDTO

// validation으로 예외처리
@NotBlank
private String content;
  • 일정이 DB에 저장되지 않은 경우
CommentService.createComment

// save 후 commentRepository에서 조회 및 예외처리
commentRepository.save(comment);
        return commentRepository.findById(comment.getCommentId()).orElseThrow(()
        -> new IllegalArgumentException("저장에 오류가 발생했습니다."));

3단계 : 댓글 수정

기능

  • 선택한 일정의 댓글을 수정합니다.

조건

  • 댓글이 수정되었다면 수정된 댓글을 반환합니다.
  • 댓글 내용만 수정 가능합니다.
  • 선택한 일정과 댓글이 DB에 저장되어 있어야 합니다.

⚠️ 예외 처리

  • 선택한 일정이나 댓글의 ID를 입력 받지 않은 경우
  • 일정이나 댓글이 DB에 저장되지 않은 경우
  • 선택한 댓글의 사용자가 현재 사용자와 일치하지 않은 경우

위와 다르지 않음.

4단계 : 댓글 삭제

기능

  • 선택한 일정의 댓글을 삭제합니다.

조건

  • 성공했다는 메시지와 상태 코드 반환하기
  • 선택한 일정과 댓글이 DB에 저장되어 있어야 합니다.

⚠️ 예외 처리

  • 선택한 일정이나 댓글의 ID를 입력받지 않은 경우
  • 일정이나 댓글이 DB에 저장되지 않은 경우
  • 선택한 댓글의 사용자가 현재 사용자와 일치하지 않은 경우

5단계 : JWT

기능

  • JWT를 이용한 인증/인가를 구현한다.
  • 위 1~4 단계에서 인증/인가가 완료된 후에만 기능이 동작하도록 수정한다.

조건

  • Access Token 만료시간 60분
  • Refresh Token 구현은 8단계이므로 이번에는 하지 않습니다.

⚠️ 예외 처리

  • 공통조건
    • StatusCode : 400
    • client에 반환
  • 토큰이 필요한 API 요청에서 토큰을 전달하지 않았거나 정상 토큰이 아닐 때
    • 에러 메세지 : 토큰이 유효하지 않습니다.
  • 토큰이 있고, 유효한 토큰이지만 해당 사용자가 작성한 게시글/댓글이 아닐 때
    • 에러 메세지 : 작성자만 삭제/수정할 수 있습니다.
  • DB에 이미 존재하는 username으로 회원가입을 요청할 때
    • 에러 메세지 : 중복된 username 입니다.
  • 로그인 시, 전달된 usernamepassword 중 맞지 않는 정보가 있을 때
    • 에러 메시지 : 회원을 찾을 수 없습니다.

6단계 : 회원가입

기능

  • 사용자의 정보를 전달 받아 유저 정보를 저장한다.

조건

  • 패스워드 암호화는 하지 않습니다.
    • PasswordEncoder() 사용할 필요없음
  • username최소 4자 이상, 10자 이하이며 알파벳 소문자(a~z), 숫자(0~9)로 구성되어야 한다.
  • password최소 8자 이상, 15자 이하이며 알파벳 대소문자(a~z, A~Z), 숫자(0~9)로 구성되어야 한다.
// 정규식을 이용한 제약조건
    @NotBlank
    @Pattern(regexp = "^[a-z0-9]{4,10}$")
    private String username;

    @NotBlank
    @Pattern(regexp = "^[A-Za-z0-9]{8,15}$")
    private String password;
  • DB에 중복된 username이 없다면 회원을 저장하고 Client 로 성공했다는 메시지, 상태코드 반환하기

7️⃣단계 - 로그인

기능

  • username, password 정보를 client로부터 전달받아 토큰을 반환한다.

설명

  • DB에서 username을 사용하여 저장된 회원의 유무를 확인한다.
    • 저장된 회원이 있다면 password 를 비교하여 로그인 성공 유무를 체크한다.

조건

  • 패스워드 복호화는 하지 않습니다.
  • 로그인 성공 시 로그인에 성공한 유저의 정보와 JWT를 활용하여 토큰을 발급한다.
  • 발급한 토큰을 Header에 추가하고 성공했다는 메시지 및 상태코드와 함께 client에 반환한다.

7단계 : 로그인

기능

  • username, password 정보를 client로부터 전달받아 토큰을 반환한다.

설명

  • DB에서 username을 사용하여 저장된 회원의 유무를 확인한다.
    • 저장된 회원이 있다면 password 를 비교하여 로그인 성공 유무를 체크한다.

조건

  • 패스워드 복호화는 하지 않습니다.
  • 로그인 성공 시 로그인에 성공한 유저의 정보와 JWT를 활용하여 토큰을 발급한다.
  • 발급한 토큰을 Header에 추가하고 성공했다는 메시지 및 상태코드와 함께 client에 반환한다.

8단계 : Refresh Token (미구현)

기능

  • 5단계에서 구현한 JWT를 Refresh Token을 사용하도록 변경

설명

  • 세션 관리
    • 자주 로그인을 반복하지 않으면서 긴 유효 기간을 가진 Refresh Token을 통해 사용자가 시스템에 지속적으로 연결되어 있을 수 있습니다.
  • 리소스 관리
    • 서버가 세션 상태를 유지할 필요 없습니다. 클라이언트 측에서 JWT를 관리하기 때문에 서버는 세션을 위해 추가적인 자원을 사용하지 않아도 됩니다.
    • 여기서 클라이언트 → Postman

조건

  • Access Token 유효기간이 지난 후 Refresh Token 갱신하지 않으면 접근 불가
  • Refresh Token 만료가 되면 인증 실패 처리 및 재로그인 유도
  • 스프링 시큐리티 사용하지 않고 5단계에서 구현한 JWT 기능에 Refresh Token만 추가 구현

9단계 : 일정과 댓글 수정

기능

  • 로그인 한 사용자에 한하여 일정과 댓글을 작성하고 수정할 수 있는 기능
  • ‘만료되지 않은 유효 토큰’인 경우에만 일정과 댓글 ‘생성’이 가능하도록 변경
  • 조회는 누구나 할 수 있습니다!

설명

  • 보안
    • 사용자 인증을 통해 접근을 제어하여 보안을 강화합니다. 또한 개인 로그를 적재하고 분석하면 모니터링도 가능합니다.
  • 사용자 경험
    • 로그인을 통해 개인을 식별하고 개인에 맞춘 서비스를 제공할 수 있습니다. 이를 통해 사용자 경험을 향상시킬 수 있습니다. 또한 사용자 추적을 통해 맞춤 서비스를 개발할 수 있습니다.

조건

  • 로그인을 하지 않으면 기능을 사용할 수 없다.
  • 유효한 토큰인 경우에만 일정과 댓글을 작성할 수 있다.
  • 일정을 생성한 사용자와 동일한 username이면 수정할 수 있다.
  • 댓글을 작성한 사용자와 동일한 username이면 수정할 수 있다.

10단계 : 파일 첨부

기능

  • 각 일정에 파일 첨부 가능

설명

  • 데이터 형식 이해
    • 파일을 데이터베이스에 저장할 때 사용하는 데이터 형식인 이진 데이터 blob에 대해 이해할 수 있습니다.
  • 텍스트 데이터 처리
    • 이진 데이터를 처리하면서 파일 입출력과 데이터 스트림 처리 등 기술에 대해 이해할 수 있습니다.

조건

  • 파일 테이블 생성
  • 일정에 파일을 첨부할 수 있는 기능
  • 일정과 파일 테이블 간 연간관계 형성
    • 1:1 매핑
    • ERD에도 파일 모델을 추가합니다.

Entity 추가 : File

파일 필드데이터 유형
아이디bigint
파일이름varchar
파일 확장자varchar
파일 크기int
생성일자timestamp
파일 콘텐츠blob

  • 일정을 생성할 때 파일을 첨부할 수 있다.
  • 일정을 수정할 때 파일을 첨부된 파일을 수정할 수 있다.

⚠️ 예외 처리

  • 일정을 삭제할 때 파일도 함께 삭제된다.
  • 파일 형식은 png, jpg만 가능하다.
  • 용량은 최대 5MB까지만 가능하다.
profile
둘뺌

0개의 댓글