-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #72 from Drink-Easy/dev
#70 Merge: 애플 로그인 합병
- Loading branch information
Showing
18 changed files
with
369 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.drinkeg.drinkeg.config; | ||
|
||
|
||
import com.drinkeg.drinkeg.DrinkegApplication; | ||
import feign.Logger; | ||
import org.springframework.cloud.openfeign.EnableFeignClients; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
@EnableFeignClients(basePackageClasses = DrinkegApplication.class) | ||
public class FeignConfig { | ||
@Bean | ||
Logger.Level feignLoggerLevel(){ | ||
return Logger.Level.FULL; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,4 +34,5 @@ public RedisTemplate<String, Object> redisTemplate() { | |
|
||
return redisTemplate; | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
src/main/java/com/drinkeg/drinkeg/dto/AppleLoginDTO/AppleLoginRequestDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.drinkeg.drinkeg.dto.AppleLoginDTO; | ||
|
||
|
||
import jakarta.validation.constraints.NotEmpty; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class AppleLoginRequestDTO { | ||
|
||
@NotEmpty | ||
private String identityToken; // 프론트한테 유저 정보가 들어있는 identityToken | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/com/drinkeg/drinkeg/dto/AppleLoginDTO/ApplePublicKeyResponseDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.drinkeg.drinkeg.dto.AppleLoginDTO; | ||
|
||
|
||
import com.drinkeg.drinkeg.apipayLoad.code.status.ErrorStatus; | ||
import com.drinkeg.drinkeg.apipayLoad.handler.TempHandler; | ||
import lombok.Getter; | ||
|
||
import java.util.List; | ||
|
||
// 애플 서버에서 주는 공개키 (public key) DTO | ||
@Getter | ||
public class ApplePublicKeyResponseDTO { | ||
|
||
private List<ApplePublicKey> keys; | ||
|
||
@Getter | ||
public static class ApplePublicKey { | ||
private String kty; | ||
private String kid; | ||
private String use; | ||
private String alg; | ||
private String n; | ||
private String e; | ||
} | ||
|
||
// 여러개 받은 공개 키 중에 Identity Token과 kid와 alg가 일치하는 토큰 찾아주는 메서드 | ||
public ApplePublicKey getMatchedKeyBy(String kid, String alg) { | ||
return keys.stream() | ||
.filter(key -> key.getKid().equals(kid) && key.getAlg().equals(alg)) | ||
.findAny() | ||
.orElseThrow(() -> new TempHandler(ErrorStatus.MATCH_PUBLIC_KEY_NOR_FOUND)); | ||
} | ||
|
||
|
||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/drinkeg/drinkeg/fegin/AppleAuthClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.drinkeg.drinkeg.fegin; | ||
|
||
import com.drinkeg.drinkeg.dto.AppleLoginDTO.ApplePublicKeyResponseDTO; | ||
import org.springframework.cloud.openfeign.FeignClient; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
|
||
|
||
// 공개키를 요청함 | ||
// url은 https://appleid.apple.com/auth/keys | ||
|
||
@FeignClient(name= "appleAuthClient", url = "https://appleid.apple.com/auth/keys") | ||
public interface AppleAuthClient { | ||
@GetMapping | ||
ApplePublicKeyResponseDTO getAppleAuthPublicKey(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,4 +51,5 @@ public boolean checkExistsValue(String key) { | |
throw new GeneralException(ErrorStatus.REDIS_NOT_FOUND); | ||
} | ||
} | ||
} | ||
} | ||
|
114 changes: 114 additions & 0 deletions
114
src/main/java/com/drinkeg/drinkeg/service/loginService/AppleLoginService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package com.drinkeg.drinkeg.service.loginService; | ||
|
||
import com.drinkeg.drinkeg.domain.Member; | ||
import com.drinkeg.drinkeg.dto.AppleLoginDTO.AppleLoginRequestDTO; | ||
import com.drinkeg.drinkeg.dto.loginDTO.oauth2DTO.LoginResponse; | ||
import com.drinkeg.drinkeg.fegin.AppleAuthClient; | ||
import com.drinkeg.drinkeg.jwt.JWTUtil; | ||
import com.drinkeg.drinkeg.redis.RedisClient; | ||
import com.drinkeg.drinkeg.repository.MemberRepository; | ||
import com.drinkeg.drinkeg.utils.ApplePublicKeyGenerator; | ||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import io.jsonwebtoken.Claims; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import lombok.NoArgsConstructor; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.security.oauth2.core.ClaimAccessor; | ||
import org.springframework.stereotype.Service; | ||
|
||
import javax.naming.AuthenticationException; | ||
import javax.print.DocFlavor; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.PublicKey; | ||
import java.security.spec.InvalidKeySpecException; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class AppleLoginService { | ||
|
||
private final TokenService tokenService; | ||
private final AppleAuthClient appleAuthClient; | ||
private final ApplePublicKeyGenerator applePublicKeyGenerator; | ||
private final MemberRepository memberRepository; | ||
private final RedisClient redisClient; | ||
private final JWTUtil jwtUtil; | ||
|
||
public LoginResponse appleLogin(AppleLoginRequestDTO appleLoginRequestDTO, HttpServletResponse response)throws AuthenticationException, NoSuchAlgorithmException, InvalidKeySpecException, | ||
JsonProcessingException { | ||
|
||
System.out.println("--------------apple Login Start---------------"); | ||
|
||
String identityToken = appleLoginRequestDTO.getIdentityToken(); | ||
|
||
// identity Token에서 헤더 추출 | ||
final Map<String, String> appleTokenHeader = tokenService.parseHeaders(appleLoginRequestDTO.getIdentityToken()); | ||
|
||
// 애플 서버에서 publicKey 받아온 후에 identity 토큰의 헤더와 일치하는 publicKey 만들기 | ||
PublicKey publicKey = applePublicKeyGenerator.generatePublicKey(appleTokenHeader, | ||
appleAuthClient.getAppleAuthPublicKey()); | ||
|
||
// identity Token에서 claims 추출 | ||
Claims claims = tokenService.getTokenClaims(identityToken, publicKey); | ||
|
||
// 회원 가입 된 사용자인지 확인하기 | ||
String username = "apple "+ claims.getSubject(); | ||
Optional<Member> existData = memberRepository.findByUsername(username); | ||
|
||
|
||
if (existData.isEmpty()){ | ||
|
||
Member member = Member.builder() | ||
.username(username) | ||
.email(claims.get("email", String.class)) | ||
.role("ROLE_USER") | ||
.isFirst(true) | ||
.build(); | ||
memberRepository.save(member); | ||
|
||
System.out.println("첫 로그인임"); | ||
|
||
jwtProvider(member, response); | ||
|
||
return LoginResponse.builder() | ||
.username(username) | ||
.role(member.getRole()) | ||
.isFirst(member.getIsFirst()) | ||
.build(); | ||
|
||
} | ||
else{ | ||
|
||
Member member = existData.get(); | ||
member.updateEmail(claims.get("email", String.class)); | ||
|
||
System.out.println("첫 로그인아님"); | ||
memberRepository.save(member); | ||
|
||
jwtProvider(member, response); | ||
|
||
return LoginResponse.builder() | ||
.username(username) | ||
.role(member.getRole()) | ||
.isFirst(member.getIsFirst()) | ||
.build(); | ||
} | ||
} | ||
|
||
public void jwtProvider(Member member, HttpServletResponse response) { | ||
|
||
String accessToken = jwtUtil.createJwt("access",member.getUsername(), member.getRole(), 60000000000L); // 임의로 10000배로 해놓았음. 나중에 수정 필요. | ||
String refreshToken = jwtUtil.createJwt("refresh",member.getUsername(), member.getRole(),864000000L); | ||
|
||
// 토큰을 쿠키에 저장하여 응답 | ||
response.addCookie(tokenService.createCookie("accessToken", accessToken)); | ||
response.addCookie(tokenService.createCookie("refreshToken", refreshToken)); | ||
response.setStatus(HttpStatus.OK.value()); | ||
|
||
// redis에 refresh 토큰 저장 | ||
redisClient.setValue(member.getUsername(), refreshToken, 864000000L); | ||
} | ||
|
||
} |
Oops, something went wrong.