Backend/Spring

Spring boot 3.x OAuth2(Google, Kakao) 로그인/회원가입 구현 2 - API 개발

keepbang 2024. 10. 2. 20:25

▤ 목차

     

    이전글

    2024.07.31 - [Backend/Spring] - Spring boot 3.x OAuth2(Google, Kakao) 로그인/회원가입 구현 - Flutter

     

    Spring boot 3.x OAuth2(Google, Kakao) 로그인/회원가입 구현 - Flutter

    ▤ 목차🙇‍♂️ Flutter 개발자가 아니라 코드 작성부분은 다소 생략하였습니다.ㅠㅠ  Flutter로 하는 OAuth2 로그인 방법Spring security로 OAuth2로그인을 구현 하려고 하면 보통 web으로 로그인 하는게

    keepbang.tistory.com

     

     


     

    로그인/회원가입 API

    이번 글에서는 Flutter에서 호출하는 로그인 / 회원가입 API를 살펴보겠습니다.
    이전글을 보셨다면 아시겠지만 사용한 API는 한 개입니다!

     

    API의 프로세스는 다음과 같습니다.

    1. Flutter에서 provider에 따라 로그인을 진행하고 accessToken을 spring 서버로 전달
    2. 서버에서 accessToken으로 사용자 정보 요청
      1. 여기에서 만약 accessToken이 변형되었다면 사용자 정보를 못가져오고 실패하게 됨
    3. 사용자 정보가 성공적으로 조회되면 해당 사용자 데이터가 DB에 저장되어있는지 확인
      1. DB에 없을 경우 사용자 생성
    4. 토큰 발급 후 응답 보냄

    위와 같은 로직으로 구성 되어있습니다. 그러면 하나하나 살펴 보겠습니다

     

     

    Controller

    ...
    
    private final OAuthClient oAuthClient;
    
    private final TokenCreate tokenCreate;
    
    @PostMapping("/login/{provider}")
      public ResponseEntity<TokenResponse> login(
          @PathVariable("provider") SocialType type,
          @RequestBody TokenRequest request
      ) {
    
        OAuth2UserInfo oAuth2UserInfo = oAuthClient.getOAuth2UserInfo(type, request.code());
    
        TokenResponse response = tokenCreate.getOAuthAccessTokenByUserInfo(type,
            oAuth2UserInfo);
            
        return ResponseEntity.ok().body(response);
    }
    
    ...

     

    API의 전체적인 구조 입니다. TokenRequest에는 accessToken이 들어가 있고 oAuthClient.getAuth2UserInfo 메소드로 소셜 타입별 사용자 정보를 가져오게 됩니다.

     

    OAuthClient는 소셜 로그인에서 다른 서버와의 연동을 위한 컴포넌트입니다.

    TokenCreate는 토큰을 생성하는 기능이 담긴 컴포넌트입니다.

    accessToken으로 사용자 정보 요청

    @Component
    @RequiredArgsConstructor
    public class OAuthClient {
      private final WebClient webClient;
    
      @Value("${spring.security.oauth2.client.provider.google.user-info-uri}")
      private String googleUserUrl;
    
      @Value("${spring.security.oauth2.client.provider.kakao.user-info-uri}")
      private String KAKAO_USER_URL;
    }

     

    OAuthClient에서 사용자 정보를 가져오는건 WebClient를 사용했고 각 provider별 document에 있는 사용자 조회 API를 사용해야합니다.

     

    • google은 spring boot에 기본값으로 들어가 있습니다.

     

     

    ...
      private JsonNode getUserInfo(String url, String token) {
        Mono<JsonNode> response = webClient.get()
            .uri(url)
            .header("Authorization", "Bearer " + token)
            .retrieve()
            .bodyToMono(JsonNode.class);
    
        return response.block();
      }
      ...

     

    token에 accessToken을 넣어서 요청하면 유효할 경우 사용자 정보를 가져올 수 있습니다. 가져온 사용자정보는 각 API 응답에따라 파싱해서 사용하면 됩니다.

    DB 데이터 확인 & 토큰 발급

    tokenCreate.getOAuthAccessTokenByUserInfo 메소드를 사용하면 토큰을 발급 할 수 있다.

    ...
    
    // 사용자 조회
    Optional<User> oUser = userManager.findByEmailAndSocialType(userInfo.getEmail(), type);
    User user = oUser.orElseGet(() -> addUser(type, userInfo));
    
    // refreshToken 초기화
    String refreshToken = this.createRefreshToken();
    this.updateRefreshToken(user,refreshToken);
    
    // 토큰 발급
    return new TokenResponse(
        this.createAccessToken(user),
        refreshToken,
        user.getUserKey()
    );
    
    ...

     

    1. accessToken으로 가져온 사용자 정보에 email을 기준으로 사용자 존재 유무를 판단합니다. 일단 이부분은 전화번호로도 바꿀수 있을 것 같아요. 그 후 사용자가 존재하지 않으면 새로 DB에 저장을 합니다.
    2. refreshToken도 초기화를 해주고 기존에 존재하던 refreshToken을 업데이트 합니다.
      (로그아웃 후 다시 로그인을 하면 refreshToken 유효 기간이 늘어납니다)
    3. 그 후 해당 사용자로 토큰을 만들고 응답으로 내보냅니다.

     


     

    처음 로그인 및 회원가입 기능을 개발해 봤는데 로그인 방식이나 회원가입 방식이 다양해서 그 방법을 고민하느라 시간이 좀 더 걸린거같네요ㅠㅠ...

     

    이 방식이 맞는지는 모르겠지만 진행하면서 만약 취약점같은게 보이면 계속 적용해봐야할것 같습니다!