Skip to content

feat: 애플 소셜 로그인 구현#53

Open
jinwon1234 wants to merge 5 commits intomainfrom
feat/52-apple-login
Open

feat: 애플 소셜 로그인 구현#53
jinwon1234 wants to merge 5 commits intomainfrom
feat/52-apple-login

Conversation

@jinwon1234
Copy link
Collaborator

변경점 👍

close: #52

애플 소셜 로그인을 구현했습니다.
카카오/구글/네이버의 소셜 로그인이랑 과정이 너무 많이 달라서 애를 많이 먹었습니다.

  1. Swift 에서 애플 로그인을 하고 authorization_code와 identity_token을 발급받는다.
  2. identity_token는 public key로 파싱하여 email, appleId를 얻는다.
  3. 서버 자체적으로 client_secret을 만들고 이를 authorization_code와 함께 apple server에 전송해서 apple server의 refresh_token을 얻는다. (apple server의 refresh_token은 회원탈퇴시 사용됩니다.)

요약하자면 위와 같은 플로우를 갖습니다.

identity_token = 애플 소셜 로그인한 사용자의 정보가 들어있는 base64로 인코딩된 토큰
public key = 애플에서 제공하는 identity_token을 검증하기 위한 공개키
authorization_code = 애플 소셜 로그인 성공 후 발급되는1회용 인증 코드
refresh_token = 만료기간이 없는 애플에서 관리하는 사용자에 대한 리프래시 토큰 (최초 로그인 시만 발급, 회원 탈퇴에 사용)
client_secret = 이 요청을 보내는 서버가 Apple Developer 계정을 가진 실제 앱 서버인지 증명하는 키

@jinwon1234 jinwon1234 requested a review from sinsehwan March 15, 2026 16:15
@jinwon1234 jinwon1234 self-assigned this Mar 15, 2026
@jinwon1234 jinwon1234 added the enhancement New feature or request label Mar 15, 2026
Copy link
Collaborator

@sinsehwan sinsehwan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변경사항 확인했습니다! 다만 aud 검증 부분 한 번 체크해주세요

Comment on lines +4 to +8
String access_token,
String expires_in,
String id_token,
String refresh_token,
String token_type
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사소하긴 한데 카멜 케이스 + @JsonProperty 적용하면 좋을 것 같습니다

Comment on lines +79 to +80
if (!clientId.equals(tokenClaims.getAudience())) {
throw new AuthenticationException(ExceptionCode.INVALID_TOKEN.getDescription());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 tokenClims.getAudience() 반환형태가 Set인 것 같은데 !tokenClaims.getAudience().contains(clientId)로 수정해야 할 것 같습니다!

Comment on lines +70 to +79
return Jwts.builder()
.setHeaderParam("kid", kid)
.setHeaderParam("alg", "ES256")
.setIssuer(teamId)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(expirationDate)
.setAudience("https://appleid.apple.com")
.setSubject(clientId)
.signWith(SignatureAlgorithm.ES256, getPrivateKey())
.compact();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jjwt 0.12~ 부터 deprecated된 함수들이 꽤 있는 것 같아요 찾아보니까 다음과 같이 쓰는 것 같던데 확인해주세요~

Jwts.builder()
      .header().keyId(kid).add("alg", "ES256").and()
      .issuer(teamId)
      .issuedAt(new Date())
      .expiration(expirationDate)
      .audience().add("https://appleid.apple.com").and()
      .subject(clientId)
      .signWith(getPrivateKey(), Jwts.SIG.ES256)


private void joinAppleUser(UserEntity userEntity, OAuth2Response oAuth2Response) {

AppleOAuth2Rep appleOAuth2Rep = (AppleOAuth2Rep) oAuth2Response;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뭔가 UserService에서 apple 관련 의존 제거하면서 타입 캐스팅 안전하게 할 수 있으면 더 좋을 것 같은데 나중에 좀 더 고민해봐야겠네요

Comment on lines +82 to +92
private PrivateKey getPrivateKey() {
try {
Reader pemReader = new StringReader(privateKey.replace("\\n", "\n"));
PEMParser pemParser = new PEMParser(pemReader);
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
PrivateKeyInfo object = (PrivateKeyInfo)pemParser.readObject();
return converter.getPrivateKey(object);
} catch (IOException e) {
throw new AuthenticationException(ExceptionCode.INVALID_TOKEN.getDescription());
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생성되는 PrivateKey가 항상 같으니 나중에 캐싱 적용해봐도 좋을 것 같아요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

애플 소셜 로그인

2 participants