SWM-99-degree / jariBean

SWM 14th JariBean Project
0 stars 1 forks source link

[FEAT] Apple Social Login 구현 #179

Closed isayaksh closed 1 year ago

isayaksh commented 1 year ago

✏️ Description

Apple 소셜 로그인 기능을 구현하였다.

기존의 존재하는 abstract class OAuthService를 상속 받아서 access token과 user information을 추출하는 추상 메소드를 구현하였다.

OAuthService

public abstract String getAccessToken(String code);
public abstract SocialUserInfo getUserInfo(String accessToken);

Access Token 발급

"https://appleid.apple.com/auth/token" 엔드 포인트로 Apple에서 response를 받는다. response의 구조는 다음과 같다.

{
  "access_token": "adg61...67Or9",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "rca7...lABoQ",
  "id_token": "eyJra...96sZg"
}

response에서 우리가 사용할 정보는 id_token에 담겨져 있다. 따라서 id_token에 해당하는 값을 반환해 준다.

getAccessToken()

@Override
public String getAccessToken(String code) {
    MultiValueMap<String, String> bodyValue = new LinkedMultiValueMap<>();
    bodyValue.add("client_id", CLIENT_ID);
    bodyValue.add("client_secret", createClientSecret());
    bodyValue.add("code", code);
    bodyValue.add("grant_type", "authorization_code");

    WebClient client = WebClient.create();
    return client.post()
            .uri("https://appleid.apple.com/auth/token")
            .contentType(APPLICATION_FORM_URLENCODED)
            .bodyValue(bodyValue)
            .retrieve()
            .bodyToMono(AppleOAuthInfo.class)
            .block()
            .getId_token();
}

사용자 정보 조회

id_token은 JWT이고 id_token의 payload에는 sub 라는 정보가 있는데 해당 정보는 모든 사용자가 유니크한 값을 가지고 있다. 따라서 로그인시 사용자를 식별할 키로 sub를 사용하기로 하였다.

getUserInfo()

@Override
public SocialUserInfo getUserInfo(String accessToken) {

    // extract sub of jwt payload
    String encodedPayload = accessToken.split(("\\."))[1];
    byte[] payloadBytes = Base64.decodeBase64(encodedPayload);
    String payload = new String(payloadBytes);
    JSONObject jsonPayload = new JSONObject(payload);
    String sub = jsonPayload.get("sub").toString();

    return SocialUserInfo.create(
            REGISTRATION,
            sub,
            "Guest",
            null
    );
}