[JWT] SpringSecurity + JWT를 사용하여 로그인, 회원가입 구현 - 2

Donghoon Jeong·2024년 2월 21일
0

JWT

목록 보기
3/4

전 포스팅에서 Spring Security와 JWT를 사용하여 회원가입과 로그인 기능을 구현해 보았는데
이번 포스팅에서는 Postman을 사용하여 해당 기능들이 잘 작동하는지 테스트를 해보겠습니다.


1. DTO 생성

MemberRequestDTO.java

회원가입 및 로그인 요청을 보내기 위해 사용할 MemberRequestDTO를 생성합니다.

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class MemberRequestDTO {

    @NotBlank
    private String username;

    @NotBlank
    private String password;

    public Member toMember(PasswordEncoder passwordEncoder) {
        return Member.builder()
                .username(username)
                .password(passwordEncoder.encode(password))
                .roles(Collections.singletonList("ROLE_USER"))
                .build();
    }
}

TokenRequestDTO.java

AccessToken을 재발급 받을 때, 사용할 TokenRequestDTO를 생성합니다.

@Getter
@NoArgsConstructor
public class RefreshTokenDTO {

    @NotEmpty
    String refreshToken;
}

2.SecurityUtil 구현

SecurityUtil.java

@Slf4j
@RequiredArgsConstructor
public class SecurityUtil {

    // SecurityContext 에 유저 정보가 저장되는 시점
    // Request 가 들어올 때 JwtFilter 의 doFilter 에서 저장
    public static Long getCurrentMemberId() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null || authentication.getName() == null) {
            throw  new RuntimeException("Security Context 에 인증 정보가 없습니다.");
        }

        return Long.parseLong(authentication.getName());
    }
}

static method인 getCurrentUsername()을 호출하여 SecurityContext에 저장된 현재 요청을 보낸 회원의 username을 간단하게 얻을 수 있습니다. 이 메서드를 활용하여 해당 회원의 특정 TODO LIST를 조회하는 작업등을 진행하였습니다.

3. MemberController 구현

테스트를 하기 위해 다음과 같은 과정을 진행하겠습니다.

  1. 회원가입

  2. 로그인을 통해 AccessToken 발급

  3. 발급받은 AccessToken을 header에 넣어 API 요청

  4. AccessToken 만료 시, RefresToken을 통해 재발급

다음과 같은 테스트를 진행하기 위해 다음과 같은 MemberController를 구현하였습니다.

MemberController.java

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {
    private final AuthService authService;

    @PostMapping("/signup")
    public ResponseEntity<MemberResponseDTO> signup(@RequestBody @Valid MemberRequestDTO memberRequestDTO) {
        return ResponseEntity.ok(authService.signup(memberRequestDTO));
    }

    @PostMapping("/login")
    public ResponseEntity<TokenDTO> login(@RequestBody @Valid MemberRequestDTO memberRequestDTO) {
        return ResponseEntity.ok(authService.login(memberRequestDTO));
    }

    @PostMapping("/reissue")
    public ResponseEntity<TokenDto> reissue(@RequestBody @Valid RefreshTokenDto refreshTokenDto) {
        return ResponseEntity.ok(authService.reissue(refreshTokenDto));
    }
}

4. 테스트

회원가입

username과 password를 JSON 형식으로 Request Body에 넣어서 요청을 보냈고, 그에 따른 결과가 성공적으로 출력되는 것을 볼 수 있습니다.

그리고 데이터베이스에도 password가 암호화된 상태로 저장된 것을 확인할 수 있습니다.

로그인을 통해 AccessToken 발급

로그인도 회원가입과 동일하게 JSON 형식으로 Request Body에 넣어서 요청을 보내주었습니다.
성공적으로 AccessToken과 RefreshToken이 출력되는 것을 볼 수 있습니다.

발급받은 AccessToken을 header에 넣어 API 요청

다음과 같이 Header의 Key에 Authorization, Value에 Bearer과 로그인 시 발급받은 Access Token 을 넣어 미리 만들어둔 API 요청을 보내면 정상적으로 실행되는 것을 볼 수 있습니다.

AccessToken 만료 시, RefresToken을 통해 재발급

AccessToken이 만료되었을 때, JSON 형식으로 Request Body에 로그인 시에 흭득한 RefreshToken을 넣어서 재발급 요청을 보내면 다음과 같이 토큰이 재발급되는 것을 확인할 수 있습니다.

profile
정신 🍒 !

0개의 댓글