[Project] 1. JWT 토큰 발급

Hayoon·2022년 8월 9일
0

Spring 정리

목록 보기
4/11

JWT 토큰이란.

JWT 는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자 만 구성된)의 JSON입니다.
전자 서명은 JSON 의 변조를 체크 할 수 있게 되어 있습니다.
JWT는 속성 정보 (Claim)를 JSON 데이터 구조로 표현한 토큰으로 RFC7519 표준 입니다.
JWT는 서버와 클라이언트 간 정보를 주고 받을 때 Http 리퀘스트 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 인증합니다.

JWT방식은 다음과 같은 플로우를 따른다.

  1. 클라이언트에서 서버로 로그인 요청을 보낸다.
  2. 서버는 로그인 정보 확인 후 토큰을 응답한다. 이 토큰은 서버에서 보관하지 않는다.
  3. 이후 클라이언트의 2번에서 응답받은 토큰을 요청에 함께 보낸다.
  4. 서버는 토큰이 유효한지 검증하고 유효하면 로그인된 사용자라고 생각한다.

JWT 구성

Session / JWT Token 차이점.

세션/쿠키 방식과 가장 큰 차이점은 세션/쿠키는 세션 저장소에 유저의 정보를 넣는 반면, JWT는 토큰 안에 유저의 정보들이 넣는다는 점입니다. 물론 클라이언트 입장에서는 HTTP 헤더에 세션ID나 토큰을 실어서 보내준다는 점에서는 동일하나, 서버 측에서는 인증을 위해 암호화를 하냐, 별도의 저장소를 이용하냐는 차이가 발생합니다.

|| Session은 Server에서 Session ID 보관, JWT Token은 보관없이 certification.

프로젝트에 적용해보자.

  1. 계정(account) / 비밀번호(password) 및 회원정보로 회원가입.
  2. 로그인하여 JWT Token 반환
  3. JWT토큰을 Client 헤더에 등록하고, 요청 시 Spring Security에서 제한을 걸어놓은 리소스의 접근을 확인.

회원가입

//회원가입 - MemberController
    @PostMapping("/api/v3/join")
    public ResponseEntity saveMemberV3(@RequestBody CreateMemberDto createMemberDto) {
        Long memberId = userService.join(createMemberDto);
        return memberId != null ?
                ResponseEntity.ok().body("회원가입을 축하합니다.") :
                ResponseEntity.badRequest().build();
    }
    
//회원가입 - UserService
    public Long join(CreateMemberDto createMemberDto) {
        Long memberId = getRole_user(createMemberDto);
        System.out.println("memberId"+memberId);
        return memberId;
    }

    public Long getRole_user(CreateMemberDto createMemberDto) {

        return memberLoginRepository.save(Member.builder()
                        .account(createMemberDto.getAccount())
                        .pwd(passwordEncoder.encode(createMemberDto.getPwd()))
                        .address(createMemberDto.getAddress())
                        .email(createMemberDto.getEmail())
                        .name(createMemberDto.getName())
                        .createDateTime(LocalDateTime.now())
                        .updateDateTime(LocalDateTime.now())
                        .memberStatus(MemberStatus.USER)
                        .roles(Collections.singletonList("ROLE_USER"))
                        .build())
                .getId();
    }

로그인

// 로그인 - MemberController
    //0808 Hayoon
    //https://jwt.io/ 에서 Encoder -> Decoder(Payload) 확인가능.
    @PostMapping("/api/v3/login")
    public String login(@RequestBody UserDto userDto) {
        log.info("\nAccount: " + userDto.getAccount() + " Password: " + userDto.getPassword());
        Member member = memberLoginRepository.findByAccount(userDto.getAccount())
                .orElseThrow(() -> new IllegalArgumentException("가입되지 않은 ACCOUNT 입니다."));
        if (!passwordEncoder.matches(userDto.getPassword(), member.getPassword())) {
            throw new IllegalArgumentException("잘못된 비밀번호입니다.");
        }
        else
            LOGGER.info("\n로그인 성공!");
        return jwtTokenProvider.createToken(member.getUsername(), member.getRoles());
    }

https://jwt.io/에서 암호화된 JWT토큰을 복호화 할 수 있다.

아래의 블로그를 참고하여 도움을 받았습니다.
출처: https://webfirewood.tistory.com/115
출처: https://llshl.tistory.com/26

profile
Junior Developer

0개의 댓글