본문 바로가기
프로젝트/MovMag

[MovMag] 오늘 배운 것 - 20231030

by JayAlex07 2023. 10. 31.

[MovMag] 오늘 배운 것 

 

JWT 토큰

@PostMapping("/login")
public TokenDto login(
        @RequestBody  @Valid MemberLogin.Request request
) {        
	MemberLogin.Response loginInfo = memberServiceImpl.login(request);

    return "토큰이 생성되었습니다 : Bearer " + 
        tokenProvider.generateToken(loginInfo.getEmail(), loginInfo.getRole());
}
  • 토큰을 생성하고, 바로 리턴을 했다
    • 이렇게 하면 나중에 유저가 API를 사용할 때에 토큰을 계속 복사, 붙여넣기를 해야하는 불편함이 있다

 

@PostMapping("/login")
public TokenDto login(
        @RequestBody  @Valid MemberLogin.Request request
) {

    MemberLogin.Response loginInfo = memberService.login(request);

    TokenDto token = TokenDto.builder()
            .accessToken(tokenProvider.generateToken(loginInfo.getEmail(), loginInfo.getRole()))
            .tokenType("Bearer")
            .build();

    return token;
}
  • TokenDto라는 클래스를 만들어서, 토큰 정보를 넣었다
    • 추후에는 header에 이 클래스를 넣을 예정이다

 


 

UserDetails는 Entity에 사용하지 않을 것

  • Entity는 데이터를 다루는 민감한 클래스다
    • Entity는 실제 데이터를 매핑해주는 클래스
  • UserDetails는 DTO 성격이 강한만큼, DTO에서 사용해준다

 

GlobalExceptionHandler

  • 리턴 타입을 ResponseEntity로 해야, 200 + 에러 메세지가 안 뜨고, 원하는 에러 번호랑 에러 메세지가 뜨게 된다
  • 그 전에는 메세지만 리턴하다보니 HTTP 200 이 계속 나와서, 조금 거슬렸다
    • 성공이 아닌데... 성공했다는 느낌

 


 

 

Spring Security + Spring Test

아래는 전체 코드다

  • **@WebMvcTest**
    • 웹에서 사용되는 요청과 응답에 대한 테스트를 수행한다
  • **@MockBean**
    • 실제 빈 객체가 아닌 가짜 객체를 생성해서 주입하는 역할을 한다
  • **mockMvc.perform**
    • 이 부분에 `.with(SecurityMockMvcRequestPostProcessors.csrf())`을 추가한다
    • 이 것이 안 들어가면 Status Code 403 이 뜬다
  • **@WithMockUser**
    • 권한 에러를 해결하기 위한 어노테이션이다 (없으면 Status Code 401이 뜨게 된다)
    • 나중에는 여기다가 따로 권한을 설정해서 API를 테스트할 수 있다
@WebMvcTest(MemberController.class)
public class MemberControllerTest {

    @MockBean
    private TokenProvider tokenProvider;

    @MockBean
    private MemberService memberService;

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    private String EMAIL = "joons@naver.com";
    private String USERNAME = "joons";
    private String PASSWORD = "joons1234!";
    private String PHONE_NUM = "010-1234-1234";
    private String ROLE = "User";

    @Test
    @DisplayName("회원가입 성공 테스트")
    @WithMockUser
    void successRegisterMember() throws Exception {
    //given

        MemberRegister.Request request = MemberRegister.Request.builder()
                .email(EMAIL)
                .username(USERNAME)
                .password(PASSWORD)
                .phoneNum(PHONE_NUM)
                .role(ROLE)
                .build();

        MemberRegister.Response response = MemberRegister.Response.builder()
                .email(EMAIL)
                .username(USERNAME)
                .role(ROLE)
                .build();

        given(memberService.register(any()))
                .willReturn(response);
    //when
    //then
        mockMvc.perform(post("/member/register")
                        .with(SecurityMockMvcRequestPostProcessors.csrf())
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsBytes(request)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.email").exists())
                .andExpect(jsonPath("$.username").exists())
                .andExpect(jsonPath("$.role").exists())
                .andDo(print());

    }
}

Service를 테스트할 때에

  • @WebMvcTest, @SpringBootTest와 같은 테스트를 사용하면 Service만을 테스트하기가 어렵다
  • Service 클래스를 @InjectMocks로 선언함으로써, @Mock으로 선언된 가짜 객체들을 의존한 Service 객체가 생성

'프로젝트 > MovMag' 카테고리의 다른 글

[MovMag] WebClient  (0) 2023.11.06
[MovMag] ElasticSearch + MySQL  (0) 2023.11.03
[MovMag] ElasticSearch setup  (0) 2023.11.02
[MovMag] 20231031 오늘 배운 것 (@Asnyc)  (0) 2023.10.31