Skip to content

Commit

Permalink
⏪ 애플 로그인 되돌리기
Browse files Browse the repository at this point in the history
  • Loading branch information
min-0 committed Oct 25, 2024
1 parent 153b428 commit 3a95e19
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class AuthController implements AuthControllerSwagger {
public ResponseEntity<TokenResponse> appleOAuthLogin(@Valid @RequestBody AppleLoginRequest appleLoginRequest) {
// 클라이언트에서 준 code 값으로 apple의 IdToken Payload를 얻어온다
AppleSocialTokenInfoResponse tokenInfo = appleOAuthService.getTokenInfo(appleLoginRequest.appleToken());
AppleIdTokenPayload tokenPayload = TokenDecoder.decodePayload(tokenInfo.idToken(), AppleIdTokenPayload.class);
AppleIdTokenPayload tokenPayload = appleOAuthService.get(appleLoginRequest.appleToken());

// apple에서 가져온 유저정보를 DB에 저장
Member member = memberService.saveMember(tokenPayload.email(), appleLoginRequest.selectedColor());
Expand All @@ -53,7 +53,7 @@ public ReissueTokenResponse reissueToken(@Valid @RequestBody ReIssueTokenRequest
return jwtTokenService.reIssue(reissueTokenRequest.refreshToken());
}

@DeleteMapping("/withdraw")
@PostMapping("/withdraw")
public void withdraw(@Valid @RequestBody AppleWithdrawRequest withdrawRequest, AuthenticationMember authenticationMember) {
// 애플 서버에 탈퇴 요청
appleOAuthService.revoke(withdrawRequest.appleRefreshToken());
Expand Down
59 changes: 33 additions & 26 deletions src/main/java/com/dnd/dndtravel/auth/service/AppleOAuthService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.dnd.dndtravel.auth.service;

import com.dnd.dndtravel.auth.controller.request.AppleRevokeRequest;
import com.dnd.dndtravel.auth.exception.AppleTokenRevokeException;
import com.dnd.dndtravel.auth.service.dto.response.AppleSocialTokenInfoResponse;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.Jwts;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -20,46 +24,49 @@

import com.dnd.dndtravel.auth.service.dto.response.AppleIdTokenPayload;
import com.dnd.dndtravel.auth.config.AppleProperties;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

/**
* private key와 기타 설정값들로 client secret을 생성한다
* client_secret: 개발자가 생성한 Secret JWT 토큰, 개발자 계정과 연결된 Apple로 로그인 개인 키를 사용, authorization code와 refresh token 검증 요청에 해당 파라미터 필요
* client_secret을 만드는 관련 docs
* - https://developer.apple.com/documentation/accountorganizationaldatasharing/creating-a-client-secret
*
* clinet_secret jwt 토큰 디코딩 예시 형식
* {
* //JWT 헤더
* "alg": "ES256", // 토큰에 서명된 알고리즘
* "kid": "ABC123DEFG" // 개발자 계정과 연결된 계정 + private key 로 만들어진 식별자
* }
* {
* "iss": "DEF123GHIJ",// 팀ID
* "iat": 1437179036, //
* "exp": 1493298100, // 만료시간
* "aud": "https://appleid.apple.com",
* "sub": "com.mytest.app"
* }
* private key와 기타 설정값들로 client secret을 생성한다 client_secret: 개발자가 생성한 Secret JWT 토큰, 개발자 계정과 연결된 Apple로 로그인 개인 키를 사용,
* authorization code와 refresh token 검증 요청에 해당 파라미터 필요 client_secret을 만드는 관련 docs -
* https://developer.apple.com/documentation/accountorganizationaldatasharing/creating-a-client-secret
* <p>
* clinet_secret jwt 토큰 디코딩 예시 형식 { //JWT 헤더 "alg": "ES256", // 토큰에 서명된 알고리즘 "kid": "ABC123DEFG" // 개발자 계정과 연결된 계정 +
* private key 로 만들어진 식별자 } { "iss": "DEF123GHIJ",// 팀ID "iat": 1437179036, // "exp": 1493298100, // 만료시간 "aud":
* "https://appleid.apple.com", "sub": "com.mytest.app" }
*/

@RequiredArgsConstructor
@Component
@Slf4j
public class AppleOAuthService {
private final AppleClient appleClient;
private final AppleProperties appleProperties;

public AppleIdTokenPayload get(String authorizationCode) {
String idToken = appleClient.getIdToken(
appleProperties.getClientId(),
generateClientSecret(),
appleProperties.getGrantType(),
authorizationCode
).idToken();

return TokenDecoder.decodePayload(idToken, AppleIdTokenPayload.class);
}

private String generateClientSecret() {
LocalDateTime expiration = LocalDateTime.now().plusMinutes(5);

return Jwts.builder()
.header().add(JwsHeader.KEY_ID, appleProperties.getKeyId()).and()
.issuer(appleProperties.getTeamId())
.audience().add(appleProperties.getAudience()).and()
.subject(appleProperties.getClientId())
.expiration(Date.from(expiration.atZone(ZoneId.systemDefault()).toInstant()))
.issuedAt(new Date())
.signWith(getPrivateKey())
.compact();
.header().add(JwsHeader.KEY_ID, appleProperties.getKeyId()).and()
.issuer(appleProperties.getTeamId())
.audience().add(appleProperties.getAudience()).and()
.subject(appleProperties.getClientId())
.expiration(Date.from(expiration.atZone(ZoneId.systemDefault()).toInstant()))
.issuedAt(new Date())
.signWith(getPrivateKey())
.compact();
}

private PrivateKey getPrivateKey() {
Expand Down

0 comments on commit 3a95e19

Please sign in to comment.