나만의 프로젝트 배포하기 2일차

박세건·2023년 9월 7일
0

개인 프로젝트

목록 보기
2/15

OAuth2.0 의 흐름


OAuth2.0의 로그인 과정에 대해 너무나 자세히 잘 알려주고 있기때문에 참고하면 좋을거 같습니다!!

나도 OAuth를 사용하던 중에 어떻게 yml에 설정한 정보를 갖고와서 인가 코드를 받고 인가코드로 토큰을 받고 그 토큰으로 사용자 정보를 요청할 수 있는것인지 궁금했는데 이 글을 보고 해결되었다.
자료 추천

OAuth2UserService에 대해 알고 작성해보자

먼저 OAuth로그인을 통해서 사용자를 저장해야하기때문에
Member 라는 Entity 설정

package com.qkrtprjs.happyexercise.member;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Getter
@Entity
@NoArgsConstructor
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String email;


    private String picture;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private Role role;

    @Builder
    public Member(String name, String email, String picture, Role role) {
        this.name = name;
        this.email = email;
        this.picture = picture;
        this.role = role;
    }
}

먼저 회원가입 API를 만들어준뒤 이상이 없는지 테스트해보고 OAuth 로그인을 진행하자

회원 가입 API

먼저 RestController를 만들어줍니다.
이전 프로젝트를 진행할때에는 MVC패턴을 사용해서 컨트롤러에서 model에 값을 넣어서 뷰로 전달하는 방식으로 사용했다면 이번 프로젝트에서 API를 만들어줄때에는 REST-API 방식으로 진행하려고한다. 짧게나마 REST-API방식에 대해 설명하자면 자원과 HTTP메서드 방식을 통해서 API 설계하는 것이다 즉, url과 http메서드로 무슨 동작을 수행할 것인지 짐작할 수 있는 형태의 API를 뜻하고 JOSN을 리턴합니다.

package com.qkrtprjs.happyexercise.controller;

import com.qkrtprjs.happyexercise.dto.MemberSaveRequestDto;
import com.qkrtprjs.happyexercise.member.Member;
import com.qkrtprjs.happyexercise.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class MemberApiController {


    private final MemberService memberService;

    @PostMapping("/api/member")
    private Long save(@RequestBody MemberSaveRequestDto memberSaveRequestDto) {
        return memberService.save(memberSaveRequestDto);
    }
}

해당 서비스 부분

package com.qkrtprjs.happyexercise.service;

import com.qkrtprjs.happyexercise.dto.MemberSaveRequestDto;
import com.qkrtprjs.happyexercise.member.Member;
import com.qkrtprjs.happyexercise.member.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;

    @Transactional
    public Long save(MemberSaveRequestDto memberSaveRequestDto) {
        return memberRepository.save(memberSaveRequestDto.toEntity(memberSaveRequestDto)).getId();
    }
}

해당 DTO

package com.qkrtprjs.happyexercise.dto;

import com.qkrtprjs.happyexercise.member.Member;
import com.qkrtprjs.happyexercise.member.Role;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;

@Getter
@NoArgsConstructor
public class MemberSaveRequestDto {
    private String name;

    private String email;

    private String platform;

    private String picture;


    @Builder

    public MemberSaveRequestDto(String name, String email, String platform, String picture, Role role) {
        this.name = name;
        this.email = email;
        this.platform = platform;
        this.picture = picture;
    }

    public Member toEntity(MemberSaveRequestDto memberSaveRequestDto) {
        return Member.builder()
                .name(memberSaveRequestDto.getName())
                .email(memberSaveRequestDto.getEmail())
                .platform(memberSaveRequestDto.getPlatform())
                .picture(memberSaveRequestDto.getPicture())
                .role(Role.USER)
                .build();
    }

}

만들어진 API가 이상은 없는지 테스트를 진행
테스트를 진행할때에 RANDOM_PORT 방식과 MockMvc를 사용해서 테스트를 진행하였다.
월내느 TestRestTemplate를 사용해서 테스트하려고했지만 securityConfig에서 api를 사용하기위해서는 USER라는 Role이 되어야만 실행할 수 있기때문에 @WithMockUser를 사용할 수 있는 MockMvc를 사용했다.

package com.qkrtprjs.happyexercise.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qkrtprjs.happyexercise.dto.MemberSaveRequestDto;
import com.qkrtprjs.happyexercise.member.Member;
import com.qkrtprjs.happyexercise.member.MemberRepository;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WithMockUser(roles = "USER")
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class MemberApiControllerTest {

@LocalServerPort
private int port;

@Autowired
private MockMvc mvc;

@Autowired
private MemberRepository memberRepository;


@After
public void tearDown() throws Exception {
    memberRepository.deleteAll();
}

@Test
public void member_등록() throws Exception {
    //given
    String name = "qkrtprjs";
    String email = "qkrtprjs456";
    String platform = "naver";
    String picture = "picture";
    MemberSaveRequestDto dto = MemberSaveRequestDto.builder()
            .name(name)
            .email(email)
            .platform(platform)
            .picture(picture)
            .build();
    String url = "http://localhost:" + port + "/api/member";
    //when
    mvc.perform(post(url)
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(new ObjectMapper().writeValueAsString(dto)))
            .andExpect(status().isOk())
            .andDo(print());

    //then
    Member member = memberRepository.findAll().get(0);

    assertThat(member.getName()).isEqualTo(name);
    assertThat(member.getPlatform()).isEqualTo(platform);
    assertThat(member.getPicture()).isEqualTo(picture);
    assertThat(member.getEmail()).isEqualTo(email);
}

}

테스트 정상

다음 글에서 본격적으로 OAuth2UserService를 구현해보자!

profile
멋있는 사람 - 일단 하자

0개의 댓글