diff --git a/build.gradle.kts b/build.gradle.kts index 93507174..32fac553 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -74,6 +74,9 @@ dependencies { // Redis implementation("org.springframework.boot:spring-boot-starter-data-redis") + + // Caffeine + implementation("com.github.ben-manes.caffeine:caffeine:3.1.8") } kotlin { diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/controller/AuthController.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/controller/AuthController.kt index 4c79d953..445ad846 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/controller/AuthController.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/controller/AuthController.kt @@ -24,10 +24,10 @@ class AuthController( private val authService: AuthService, ) { @Operation( - summary = "카카오 로그인 API", - description = "카카오 로그인을 진행합니다." + summary = "소셜 로그인 API", + description = "소셜 로그인을 진행합니다." ) - @PostMapping("/login/kakao") + @PostMapping("/login") fun signIn( @Valid @RequestBody signInRequest: SignInRequest ): ResponseEntity> { diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/command/SignInRequestCommand.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/command/SignInRequestCommand.kt index 789514d0..2e22f7db 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/command/SignInRequestCommand.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/command/SignInRequestCommand.kt @@ -1,5 +1,8 @@ package org.appjam.smashing.domain.auth.dto.command +import org.appjam.smashing.domain.auth.enums.ProviderType + data class SignInRequestCommand( - val accessToken: String, + val idToken: String, + val provider: ProviderType, ) diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/command/SignUpRequestCommand.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/command/SignUpRequestCommand.kt index 7fdbe618..237b3e41 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/command/SignUpRequestCommand.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/command/SignUpRequestCommand.kt @@ -1,10 +1,12 @@ package org.appjam.smashing.domain.auth.dto.command +import org.appjam.smashing.domain.auth.enums.ProviderType import org.appjam.smashing.domain.sport.enums.ExperienceRange import org.appjam.smashing.domain.user.enums.Gender data class SignUpRequestCommand( - val kakaoId: String, + val socialId: String, + val provider: ProviderType, val nickname: String, val gender: Gender, val openChatUrl: String, diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/request/SignInRequest.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/request/SignInRequest.kt index 84a6eeeb..cc30ac30 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/request/SignInRequest.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/request/SignInRequest.kt @@ -2,13 +2,19 @@ package org.appjam.smashing.domain.auth.dto.request import jakarta.validation.constraints.NotBlank import org.appjam.smashing.domain.auth.dto.command.SignInRequestCommand +import org.appjam.smashing.domain.auth.enums.ProviderType +import org.appjam.smashing.global.common.validator.annotation.ValidEnum +import org.appjam.smashing.global.extensions.ofIgnoreCase data class SignInRequest( - @field:NotBlank(message = "엑세스 토큰을 입력해주세요.") - val accessToken: String?, + @field:NotBlank(message = "idToken을 입력해주세요.") + val idToken: String?, + @field:NotBlank(message = "provider를 입력해주세요.") + @field:ValidEnum(message = "잘못된 provider 값입니다.", enumClass = ProviderType::class) + val provider: String?, ) { - fun toCommand(): SignInRequestCommand = - SignInRequestCommand( - accessToken = accessToken!!, - ) + fun toCommand() = SignInRequestCommand( + idToken = idToken!!, + provider = ofIgnoreCase(provider!!), + ) } diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/request/SignUpRequest.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/request/SignUpRequest.kt index 40a2bfb8..cdb7d907 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/request/SignUpRequest.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/request/SignUpRequest.kt @@ -2,14 +2,17 @@ package org.appjam.smashing.domain.auth.dto.request import jakarta.validation.constraints.NotBlank import org.appjam.smashing.domain.auth.dto.command.SignUpRequestCommand +import org.appjam.smashing.domain.auth.enums.ProviderType import org.appjam.smashing.domain.sport.enums.ExperienceRange import org.appjam.smashing.domain.user.enums.Gender import org.appjam.smashing.global.common.validator.annotation.ValidEnum import org.appjam.smashing.global.extensions.ofIgnoreCase data class SignUpRequest( - @field:NotBlank(message = "kakaoId를 입력해주세요.") - val kakaoId: String?, + @field:NotBlank(message = "socialId를 입력해주세요.") + val socialId: String?, + @field:ValidEnum(message = "잘못된 provider 값입니다.", enumClass = ProviderType::class) + val provider: String?, @field:NotBlank(message = "nickname을 입력해주세요.") val nickname: String?, @field:NotBlank(message = "gender를 입력해주세요.") @@ -26,7 +29,8 @@ data class SignUpRequest( val region: String?, ) { fun toCommand() = SignUpRequestCommand( - kakaoId = kakaoId!!, + socialId = socialId!!, + provider = ofIgnoreCase(provider!!), nickname = nickname!!, gender = ofIgnoreCase(gender!!), openChatUrl = openChatUrl!!, diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/response/SignInResponse.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/response/SignInResponse.kt index d987460b..c5e50410 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/response/SignInResponse.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/response/SignInResponse.kt @@ -3,7 +3,7 @@ package org.appjam.smashing.domain.auth.dto.response data class SignInResponse( val accessToken: String?, val refreshToken: String?, - val kakaoId: String, + val socialId: String, val userId: String?, val nickname: String?, ) { @@ -13,13 +13,13 @@ data class SignInResponse( fun from( accessToken: String? = null, refreshToken: String? = null, - kakaoId: String, + socialId: String, userId: String? = null, nickname: String? = null, ) = SignInResponse( accessToken = accessToken, refreshToken = refreshToken, - kakaoId = kakaoId, + socialId = socialId, userId = userId, nickname = nickname, ) diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/dto/response/SocialType.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/response/SocialType.kt new file mode 100644 index 00000000..7ab8913f --- /dev/null +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/dto/response/SocialType.kt @@ -0,0 +1,8 @@ +package org.appjam.smashing.domain.auth.dto.response + +import org.appjam.smashing.domain.auth.enums.ProviderType + +data class SocialType( + val provider: ProviderType, + val socialId: String, +) diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/enums/ProviderType.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/enums/ProviderType.kt new file mode 100644 index 00000000..cd6132ba --- /dev/null +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/enums/ProviderType.kt @@ -0,0 +1,5 @@ +package org.appjam.smashing.domain.auth.enums + +enum class ProviderType { + KAKAO, APPLE +} diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/service/AuthService.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/service/AuthService.kt index 2494cdfa..0e1111e2 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/service/AuthService.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/service/AuthService.kt @@ -42,12 +42,12 @@ class AuthService( fun signIn( requestCommand: SignInRequestCommand, ): SignInResponse { - val kakaoId = socialAuthServiceManager.getKakaoId(requestCommand.accessToken) + val (provider, socialId) = socialAuthServiceManager.getSocialId(requestCommand) - val user = userRepository.findByKakaoId(kakaoId) - ?: return SignInResponse.from( - kakaoId = kakaoId, - ) + val user = userRepository.findBySocialIdAndProvider( + socialId = socialId, + provider = provider, + ) ?: return SignInResponse.from(socialId = socialId) val userId = user.id ?: throw CustomException(ErrorCode.USER_NOT_FOUND) @@ -56,7 +56,7 @@ class AuthService( return SignInResponse.from( accessToken = token.accessToken.token, refreshToken = token.refreshToken.token, - kakaoId = kakaoId, + socialId = socialId, userId = userId, nickname = user.nickname, ) @@ -81,7 +81,8 @@ class AuthService( val user = userRepository.save( User.create( - kakaoId = requestCommand.kakaoId, + socialId = requestCommand.socialId, + provider = requestCommand.provider, nickname = requestCommand.nickname, gender = requestCommand.gender, openchatUrl = requestCommand.openChatUrl.trim(), @@ -173,8 +174,8 @@ class AuthService( } private fun validateUser(requestCommand: SignUpRequestCommand) { - if (userRepository.existsByKakaoId(requestCommand.kakaoId)) { - throw CustomException(ErrorCode.DUPLICATE_KAKAO_ID) + if (userRepository.existsBySocialId(requestCommand.socialId)) { + throw CustomException(ErrorCode.DUPLICATE_SOCIAL_ID) } if (userRepository.existsByNickname(requestCommand.nickname)) { diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcJwksClient.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcJwksClient.kt new file mode 100644 index 00000000..7b19f059 --- /dev/null +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcJwksClient.kt @@ -0,0 +1,28 @@ +package org.appjam.smashing.domain.auth.social + +import com.fasterxml.jackson.databind.JsonNode +import com.github.benmanes.caffeine.cache.Cache +import com.github.benmanes.caffeine.cache.Caffeine +import org.appjam.smashing.global.exception.CustomException +import org.appjam.smashing.global.exception.ErrorCode +import org.springframework.stereotype.Component +import org.springframework.web.client.RestTemplate +import java.util.concurrent.TimeUnit + +@Component +class OidcJwksClient( + private val restTemplate: RestTemplate, +) { + private val cache: Cache = Caffeine.newBuilder() + .expireAfterWrite(1, TimeUnit.HOURS) + .maximumSize(10) + .build() + + fun getKeys( + jwksUri: String, + ): JsonNode = cache.get(jwksUri) { + restTemplate.getForObject(jwksUri, JsonNode::class.java) + ?: throw CustomException(ErrorCode.INVALID_ID_TOKEN) + } ?: throw CustomException(ErrorCode.INVALID_ID_TOKEN) + +} diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcProperties.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcProperties.kt new file mode 100644 index 00000000..886fc7d6 --- /dev/null +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcProperties.kt @@ -0,0 +1,15 @@ +package org.appjam.smashing.domain.auth.social + +import org.appjam.smashing.domain.auth.enums.ProviderType +import org.springframework.boot.context.properties.ConfigurationProperties + +@ConfigurationProperties(prefix = "oidc") +data class OidcProperties( + val kakaoClientId: String, + val appleClientId: String, +) { + fun getClientId(providerType: ProviderType): String = when (providerType) { + ProviderType.KAKAO -> kakaoClientId + ProviderType.APPLE -> appleClientId + } +} diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcTokenValidator.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcTokenValidator.kt new file mode 100644 index 00000000..8dd46855 --- /dev/null +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/social/OidcTokenValidator.kt @@ -0,0 +1,79 @@ +package org.appjam.smashing.domain.auth.social + +import com.fasterxml.jackson.databind.ObjectMapper +import io.jsonwebtoken.Jwts +import org.appjam.smashing.domain.auth.enums.ProviderType +import org.appjam.smashing.global.exception.CustomException +import org.appjam.smashing.global.exception.ErrorCode +import org.springframework.stereotype.Component +import java.math.BigInteger +import java.security.KeyFactory +import java.security.PublicKey +import java.security.spec.RSAPublicKeySpec +import java.util.* + +@Component +class OidcTokenValidator( + private val oidcProperties: OidcProperties, + private val jwksClient: OidcJwksClient, +) { + fun extractSocialId( + idToken: String, + providerType: ProviderType, + ): String { + // 회웑 정보 가져오기 + val (iss, jwksUri) = when (providerType) { + ProviderType.KAKAO -> KAKAO_ISS to KAKAO_JWKS_URI + ProviderType.APPLE -> APPLE_ISS to APPLE_JWKS_URI + } + val clientId = oidcProperties.getClientId(providerType) + + val publicKey = getPublicKey( + idToken = idToken, + jwksUri = jwksUri, + ) + + val claims = Jwts.parserBuilder() + .setSigningKey(publicKey) + .build() + .parseClaimsJws(idToken) + .body + + // 회원 검증 + if (claims.issuer != iss) throw CustomException(ErrorCode.INVALID_ISS) + if (claims.audience != clientId) throw CustomException(ErrorCode.INVALID_AUD) + + return claims.subject + } + + private fun getPublicKey( + idToken: String, + jwksUri: String, + ): PublicKey { + val header = String(Base64.getUrlDecoder().decode(idToken.split(".")[0])) + val kid = ObjectMapper().readTree(header).get(KID).asText() + + val keys = jwksClient.getKeys(jwksUri) + + val key = keys[KEYS].find { it[KID].asText() == kid } + ?: throw CustomException(ErrorCode.INVALID_ID_TOKEN) + + val n = BigInteger(1, Base64.getUrlDecoder().decode(key[N].asText())) + val e = BigInteger(1, Base64.getUrlDecoder().decode(key[E].asText())) + + return KeyFactory.getInstance(RSA) + .generatePublic(RSAPublicKeySpec(n, e)) + } + + companion object { + private const val KID = "kid" + private const val KEYS = "keys" + private const val N = "n" + private const val E = "e" + private const val RSA = "RSA" + private const val KAKAO_JWKS_URI = "https://kauth.kakao.com/.well-known/jwks.json" + private const val KAKAO_ISS = "https://kauth.kakao.com" + private const val APPLE_JWKS_URI = "https://appleid.apple.com/auth/keys" + private const val APPLE_ISS = "https://appleid.apple.com" + } +} diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/social/SocialAuthServiceManager.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/social/SocialAuthServiceManager.kt index 86b696c3..35300425 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/social/SocialAuthServiceManager.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/auth/social/SocialAuthServiceManager.kt @@ -1,11 +1,22 @@ package org.appjam.smashing.domain.auth.social -import org.appjam.smashing.domain.auth.social.kakao.KakaoAuthTokenValidator +import org.appjam.smashing.domain.auth.dto.command.SignInRequestCommand +import org.appjam.smashing.domain.auth.dto.response.SocialType import org.springframework.stereotype.Component @Component class SocialAuthServiceManager( - private val kakaoAuthTokenValidator: KakaoAuthTokenValidator, + private val oidcTokenValidator: OidcTokenValidator, ) { - fun getKakaoId(authAccessToken: String): String = kakaoAuthTokenValidator.extractKakaoId(authAccessToken) + fun getSocialId(command: SignInRequestCommand): SocialType { + val socialId = oidcTokenValidator.extractSocialId( + idToken = command.idToken, + providerType = command.provider + ) + + return SocialType( + provider = command.provider, + socialId = socialId, + ) + } } diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/KakaoApiClient.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/KakaoApiClient.kt deleted file mode 100644 index 72ee0382..00000000 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/KakaoApiClient.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.appjam.smashing.domain.auth.social.kakao - -import org.appjam.smashing.domain.auth.social.kakao.dto.response.KakaoUserResponse -import org.springframework.cloud.openfeign.FeignClient -import org.springframework.http.HttpHeaders -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.RequestHeader - -/** - * [KakaoApiClient] - * - * 카카오 API 서버와 통신하여 사용자 정보를 가져오기 위한 Feign Client - */ -@FeignClient(name = "kakaoApiClient", url = "https://kapi.kakao.com") -interface KakaoApiClient { - @GetMapping("/v2/user/me") - fun getUserInfo( - @RequestHeader(HttpHeaders.AUTHORIZATION) bearerToken: String - ): KakaoUserResponse -} diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/KakaoAuthTokenValidator.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/KakaoAuthTokenValidator.kt deleted file mode 100644 index 2e575d16..00000000 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/KakaoAuthTokenValidator.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.appjam.smashing.domain.auth.social.kakao - -import org.appjam.smashing.global.exception.CustomException -import org.appjam.smashing.global.exception.ErrorCode -import org.springframework.stereotype.Component - -@Component -class KakaoAuthTokenValidator( - private val kakaoApiClient: KakaoApiClient -) { - fun extractKakaoId(authAccessToken: String): String = - try { - val token = if (authAccessToken.startsWith(PREFIX)) authAccessToken else "$PREFIX$authAccessToken" - - val response = kakaoApiClient.getUserInfo(token) - - response.id.toString() - - } catch (e: Exception) { - throw CustomException(ErrorCode.INVALID_KAKAO_ACCESS_TOKEN) - } - - companion object { - private const val PREFIX = "Bearer " - } -} diff --git a/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/dto/response/KakaoUserResponse.kt b/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/dto/response/KakaoUserResponse.kt deleted file mode 100644 index c360d26c..00000000 --- a/src/main/kotlin/org/appjam/smashing/domain/auth/social/kakao/dto/response/KakaoUserResponse.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.appjam.smashing.domain.auth.social.kakao.dto.response - -import com.fasterxml.jackson.databind.PropertyNamingStrategies -import com.fasterxml.jackson.databind.annotation.JsonNaming - -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class) -data class KakaoUserResponse( - val id: Long, -) diff --git a/src/main/kotlin/org/appjam/smashing/domain/user/entity/User.kt b/src/main/kotlin/org/appjam/smashing/domain/user/entity/User.kt index 79f603c0..32d385d1 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/user/entity/User.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/user/entity/User.kt @@ -2,6 +2,7 @@ package org.appjam.smashing.domain.user.entity import io.hypersistence.utils.hibernate.id.Tsid import jakarta.persistence.* +import org.appjam.smashing.domain.auth.enums.ProviderType import org.appjam.smashing.domain.common.entity.BaseEntity import org.appjam.smashing.domain.user.enums.Gender import org.hibernate.annotations.Comment @@ -12,7 +13,8 @@ import java.time.LocalDateTime @Entity @Table( indexes = [ - Index(name = "idx_nickname", columnList = "nickname") + Index(name = "idx_nickname", columnList = "nickname"), + Index(name = "idx_social", columnList = "social_id, provider") ] ) @Comment("유저 정보") @@ -32,8 +34,13 @@ class User( val id: String? = null, @Column(nullable = false) - @Comment("카카오 IDX") - val kakaoId: String, + @Comment("소셜 IDX") + val socialId: String, + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 10) + @Comment("소셜 제공자") + val provider: ProviderType, @Column(nullable = false, length = 50) @Comment("닉네임") @@ -85,18 +92,19 @@ class User( const val DELETED_USER_NICKNAME = "알 수 없음" fun create( - kakaoId: String, + socialId: String, + provider: ProviderType, nickname: String, gender: Gender, openchatUrl: String, region: String, ) = User( - kakaoId = kakaoId, + socialId = socialId, + provider = provider, nickname = nickname, gender = gender, openchatUrl = openchatUrl, region = region, ) } - } diff --git a/src/main/kotlin/org/appjam/smashing/domain/user/repository/UserRepository.kt b/src/main/kotlin/org/appjam/smashing/domain/user/repository/UserRepository.kt index 9d795803..243cc4b3 100644 --- a/src/main/kotlin/org/appjam/smashing/domain/user/repository/UserRepository.kt +++ b/src/main/kotlin/org/appjam/smashing/domain/user/repository/UserRepository.kt @@ -1,12 +1,12 @@ package org.appjam.smashing.domain.user.repository +import org.appjam.smashing.domain.auth.enums.ProviderType import org.appjam.smashing.domain.user.entity.User import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query interface UserRepository : JpaRepository { - fun findByKakaoId(kakaoId: String): User? - fun existsByKakaoId(kakaoId: String): Boolean + fun existsBySocialId(socialId: String): Boolean fun existsByNickname(nickname: String): Boolean fun existsByOpenchatUrl(openChatUrl: String): Boolean @@ -21,4 +21,9 @@ interface UserRepository : JpaRepository { fun findByIdIncludingDeleted( id: String, ): User? + + fun findBySocialIdAndProvider( + socialId: String, + provider: ProviderType, + ): User? } diff --git a/src/main/kotlin/org/appjam/smashing/global/config/RestTemplateConfig.kt b/src/main/kotlin/org/appjam/smashing/global/config/RestTemplateConfig.kt new file mode 100644 index 00000000..e6626c1e --- /dev/null +++ b/src/main/kotlin/org/appjam/smashing/global/config/RestTemplateConfig.kt @@ -0,0 +1,18 @@ +package org.appjam.smashing.global.config + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.http.client.SimpleClientHttpRequestFactory +import org.springframework.web.client.RestTemplate + +@Configuration +class RestTemplateConfig { + @Bean + fun restTemplate(): RestTemplate { + val factory = SimpleClientHttpRequestFactory().apply { + setConnectTimeout(3_000) + setReadTimeout(3_000) + } + return RestTemplate(factory) + } +} diff --git a/src/main/kotlin/org/appjam/smashing/global/exception/ErrorCode.kt b/src/main/kotlin/org/appjam/smashing/global/exception/ErrorCode.kt index 9e5b32e1..777029b6 100644 --- a/src/main/kotlin/org/appjam/smashing/global/exception/ErrorCode.kt +++ b/src/main/kotlin/org/appjam/smashing/global/exception/ErrorCode.kt @@ -41,10 +41,12 @@ enum class ErrorCode( INVALID_REFRESH_TOKEN_SUBJECT(HttpStatus.UNAUTHORIZED, "AUTH-018", "리프레시 토큰의 유저 정보가 올바르지 않습니다."), INVALID_REFRESH_TOKEN_TYPE(HttpStatus.UNAUTHORIZED, "AUTH-019", "리프레시 토큰의 타입이 올바르지 않습니다."), - // Auth - Kakao Token - INVALID_KAKAO_ACCESS_TOKEN(HttpStatus.UNAUTHORIZED, "AUTH-020", "유효하지 않은 카카오 액세스 토큰입니다."), - DUPLICATE_KAKAO_ID(HttpStatus.CONFLICT, "AUTH-021", "이미 존재하는 유저입니다."), - DUPLICATE_NICKNAME(HttpStatus.CONFLICT, "AUTH-022", "이미 사용 중인 닉네임입니다."), + // Auth - SocialId Token + INVALID_ISS(HttpStatus.UNAUTHORIZED, "AUTH-020", "유효하지 않은 ID 토큰 발급자입니다."), + INVALID_AUD(HttpStatus.UNAUTHORIZED, "AUTH-021", "유효하지 않은 audience입니다."), + DUPLICATE_SOCIAL_ID(HttpStatus.CONFLICT, "AUTH-022", "이미 존재하는 유저입니다."), + DUPLICATE_NICKNAME(HttpStatus.CONFLICT, "AUTH-023", "이미 사용 중인 닉네임입니다."), + INVALID_ID_TOKEN(HttpStatus.UNAUTHORIZED, "AUTH-024", "유효하지 않은 ID 토큰입니다."), // Domain - User / Profile USER_SPORT_PROFILE_NOT_FOUND(HttpStatus.NOT_FOUND, "USER-001", "유저 스포츠 프로필을 찾을 수 없습니다."), diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 32bb00e1..65028e13 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,3 +4,7 @@ spring: timezone: default-time-zone: Asia/Seoul + +oidc: + kakao-client-id: ${KAKAO_CLIENT_ID} + apple-client-id: ${APPLE_CLIENT_ID:test_apple_id} \ No newline at end of file