230306 TIL #25 @Valid / Postman JWT / Project 정리

김춘복·2023년 3월 6일
0

TIL : Today I Learned

목록 보기
25/494

230306 Today I Learned

Spring 2주차. 심화과정 lv.2 과제를 진행했다. 저번주에 진행한 블로그 프로젝트에 JWT를 이용한 회원가입과 로그인을 구현하는 과제였는데 구현까지는 쉬운편이었으나 JWT의 정확한 메커니즘은 아직 확실하게는 이해하지 못했다. 오늘 TIL은 프로젝트 진행과정 중 겪은 문제점들을 정리해보겠다.

@Valid

참고사이트1
참고사이트2

  • 문제 : 아이디, 비밀번호에 제약조건을 걸어야 한다.

  • 시도 및 해결 :
    @Valid로 검색을 해서 해당 내용을 적용 시켜봤으나 처음엔 실패했다.
    build.gradle의 dependancies에 @Valid에 관한 내용을 추가시키지 않아서 였다.
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    을 적용해야 정상적으로 작동한다.

우선 적용은 RequestDto쪽에다 하면 되는데

@Getter
@Setter
public class SignupRequestDto {

    @Pattern(regexp = "^[a-z0-9]{4,10}", 
    message = "유저 이름은 최소 4자 이상, 10자 이하이며 알파벳 소문자와 숫자만 사용해야 합니다.")
    private String username;

    @Pattern(regexp = "^[a-zA-Z0-9]{8,15}",
    message = "비밀번호는 최소 8자 이상, 15자 이하이며 알파벳 대소문자와 숫자만 사용해야 합니다.")
    private String password;
}

이런 식으로 @Pattern(regexp="제약조건(정규식)", message="위반시 출력 메세지")
로 구성해서 컬럼 위에다 달면 된다.
그리고 Controller의 변수 앞에다가 @Valid를 추가로 달아줘야 한다.

@PostMapping("/signup")
    public MsgResponseDto signup(@RequestBody @Valid SignupRequestDto signupRequestDto) {
        return userService.signup(signupRequestDto);
    }
  • 알게된 점
    : 클라이언트 입력 값의 제약조건은 validation을 dependandy에 추가한 뒤, DTO에 정규식으로 제약조건을 걸고 @Controller 메서드의 파라미터 앞에 @Valid를 달아주면 된다.

Postman으로 JWT 인증

  • 문제 : Postman으로 해당 프로젝트 테스트 구동을 하려는데 JWT 토큰을 제대로 인식하지 못했다.

  • 시도 및 해결 : JWT 토큰 validation 과정에서 예외처리가 계속 되어서 해당 메서드를 계속 바꿔 봤으나 실패했다. 그래서 JWT에 대해 좀 더 공부해보니 같은 아이디라도 서버를 켤때마다 JWT 토큰의 값이 계속 바뀐다는 것을 알게되었다.
    그래서 로그인시 Response의 Header로 오는 JWT 토큰 Authorization의 value값을 서버를 켤 때 마다 계속 바꿔서 적용하니 해결되었다.

  • 알게된점 : 서버를 껐다 키면 같은 아이디라도 JWT 토큰의 값이 바뀐다. JWT의 값이 변하는 조건을 좀 더 알아보자.

환경변수 설정 (23.03.07)

이날 번거로웠던걸 환경변수 설정으로 해결했다.

Postman 오른쪽 구성에 가면 환경변수를 설정하는 곳이 있다.
로그인시 반환되는 JWT 토큰을 계속 복붙할 필요 없이 여기서 변수를 하나 만들고 로그인시 반환되는 토큰을 set as variable로 설정하고 {{변수이름}} 을 써서 다른 곳에 활용하면 편하게 사용할 수 있다.


프로젝트로 알게된 점 정리

  • Controller에 JWT 적용할 때 파라미터 : 서버가 JWT 줄때는 HttpServletResponse response, 클라이언트가 request로 보낼때는 HttpServletRequest request로 받으면 된다.

  • Controller에서 파라미터에 @가 생략되어있으면 기본적으로 @ModelAttribute로 받는다.

  • 서버가 JWT를 response에 넘겨 줄 때(login할 때) 반환값과 상관 없이

response.addHeader(JwtUtil.AUTHORIZATION_HEADER, jwtUtil.createToken(user.get().getUsername(), user.get().getRole()));

처럼 resonse.addHeader() 메서드만 실행해서 (key : AUTHORIZATION, value : JWT토큰) 붙여주면 된다.

  • ERD는 DB관점이다. 객체관점에서 보면 안된다. 상속관계 표현이 안되니 Timestamped같은건 테이블 따로 만들지말고 밑에 붙이는게 맞다.
    그리고 DB상에서는 대소문자 구분이 안되니 snake_case로 써야한다.
    String은 varchar, localdatetime은 date_time으로 DB에 맞는 용어를 써야 한다.

  • 외래키는 다른 테이블의 기본키를 받아오니까 username이 아니라 userid를 받아온다.

  • 토큰검증메서드처럼 중간에 private 메서드를 만들면 @Transactional은 필요 없다.

  • API 명세서는 실패한 케이스도 넣어주면 좋다.

profile
꾸준히 성장하기 위해 매일 log를 남깁니다!

0개의 댓글