Skip to content

Commit

Permalink
fix: #11 #45 Feign 종속성 문제 && redis bean 중복 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
psychology50 committed Dec 23, 2023
1 parent 21a9463 commit 1c1af45
Show file tree
Hide file tree
Showing 18 changed files with 104 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/kcy/fitapet/FitapetApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import java.util.TimeZone;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/kcy/fitapet/domain/care/domain/Care.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@Entity
@Table(name = "CARE")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"careName", "dtype"})
@ToString(of = {"careName"})
@Getter
public class Care extends Auditable {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.kcy.fitapet.domain.model.Auditable;
import com.kcy.fitapet.domain.notification.domain.Notification;
import com.kcy.fitapet.domain.notification.type.NotificationType;
import com.kcy.fitapet.domain.oauth.domain.OAuthID;
import com.kcy.fitapet.domain.oauth.domain.OauthAccount;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;
Expand Down Expand Up @@ -45,7 +45,7 @@ public class Member extends Auditable {
private NotificationSetting notificationSetting;

@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private Set<OAuthID> oauthIDs = new HashSet<>();
private Set<OauthAccount> oauthIDs = new HashSet<>();
@OneToMany(mappedBy = "from", cascade = CascadeType.ALL)
private Set<MemberNickname> fromMemberNickname = new HashSet<>();
@OneToMany(mappedBy = "to", cascade = CascadeType.ALL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void signIn(
@PostMapping("/{id}")
@PreAuthorize("isAnonymous()")
public void signUp(
@PathVariable("id") String id,
@PathVariable("id") Long id,
@RequestParam("provider") ProviderType provider,
@RequestBody @Valid OauthSignUpReq req
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class OauthAccount extends Auditable {
private Long id;

@Column(name = "oauth_id")
private Long OauthId;
private Long oauthId;
@Convert(converter = ProviderTypeConverter.class)
private ProviderType provider;
private String email;
Expand All @@ -27,17 +27,17 @@ public class OauthAccount extends Auditable {
private Member member;

@Builder
public OauthAccount(Long id, Long OauthId, ProviderType provider, String email, Member member) {
public OauthAccount(Long id, Long oauthId, ProviderType provider, String email, Member member) {
this.id = id;
this.OauthId = OauthId;
this.oauthId = oauthId;
this.provider = provider;
this.email = email;
this.member = member;
}

public static OauthAccount of(Long OauthId, ProviderType provider, String email, Member member) {
public static OauthAccount of(Long oauthId, ProviderType provider, String email, Member member) {
return OauthAccount.builder()
.OauthId(OauthId)
.oauthId(oauthId)
.provider(provider)
.email(email)
.member(member)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

public record OauthSignInReq(
@NotEmpty
String id,
Long id,
@NotEmpty
String id_token,
@NotEmpty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
public enum OauthException implements StatusCode {
/* BAD REQUEST */
INVALID_PROVIDER(HttpStatus.BAD_REQUEST, "유효하지 않은 제공자입니다."),
INVALID_OAUTH_ID(HttpStatus.BAD_REQUEST, "ID와 제공자가 일치하지 않습니다."),

/* FORBIDDEN */
NOT_FOUND_MEMBER(HttpStatus.FORBIDDEN, "존재하지 않는 회원입니다.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.kcy.fitapet.domain.oauth.service.component;

import com.kcy.fitapet.domain.member.domain.Member;
import com.kcy.fitapet.domain.oauth.exception.OauthException;
import com.kcy.fitapet.domain.oauth.service.module.OauthApplicationConfigHelper;
import com.kcy.fitapet.domain.oauth.service.module.OauthClientHelper;
import com.kcy.fitapet.domain.oauth.service.module.OauthSearchService;
import com.kcy.fitapet.domain.oauth.type.ProviderType;
import com.kcy.fitapet.global.common.response.exception.GlobalErrorException;
import com.kcy.fitapet.global.common.security.jwt.JwtUtil;
import com.kcy.fitapet.global.common.security.jwt.dto.Jwt;
import com.kcy.fitapet.global.common.security.jwt.dto.JwtUserInfo;
Expand All @@ -13,6 +15,7 @@
import com.kcy.fitapet.global.common.security.oauth.OauthOIDCHelper;
import com.kcy.fitapet.global.common.security.oauth.dto.OIDCDecodePayload;
import com.kcy.fitapet.global.common.security.oauth.dto.OIDCPublicKeyResponse;
import com.kcy.fitapet.global.common.security.oauth.kakao.KakaoOauthClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
Expand All @@ -25,18 +28,17 @@ public class OauthService {
private final OauthSearchService oauthSearchService;

private final OauthOIDCHelper oauthOIDCHelper;
private final OauthClientHelper oauthClientHelper;
private final OauthApplicationConfigHelper oauthApplicationConfigHelper;
private final OauthClientHelper oauthClientHelper;

private final JwtUtil jwtUtil;

@Transactional
public void signUpByOIDC() {

}

@Transactional
public Jwt signInByOIDC(String id, String idToken, ProviderType provider, String nonce) {
public Jwt signInByOIDC(Long id, String idToken, ProviderType provider, String nonce) {
OauthClient oauthClient = oauthClientHelper.getOauthClient(provider);
OIDCPublicKeyResponse oidcPublicKeyResponse = oauthClient.getOIDCPublicKey();
OauthApplicationConfig oauthApplicationConfig = oauthApplicationConfigHelper.getOauthApplicationConfig(provider);
Expand All @@ -45,8 +47,10 @@ public Jwt signInByOIDC(String id, String idToken, ProviderType provider, String
idToken, oauthApplicationConfig.getAuthorizationUri(),
oauthApplicationConfig.getClientId(), nonce, oidcPublicKeyResponse);

if (oauthSearchService.isExistMember(Long.parseLong(payload.sub()), provider)) {
Member member = oauthSearchService.findMemberByOauthIdAndProvider(Long.parseLong(payload.sub()), provider);
isValidRequestId(id, Long.parseLong(payload.sub()));

if (oauthSearchService.isExistMember(id, provider)) {
Member member = oauthSearchService.findMemberByOauthIdAndProvider(id, provider);
return generateToken(JwtUserInfo.from(member));
} else {
return null;
Expand All @@ -63,10 +67,18 @@ public void signUpByCode() {

}

private void isValidRequestId(Long id, Long sub) {
if (!id.equals(sub)) {
throw new GlobalErrorException(OauthException.INVALID_OAUTH_ID);
}
}

private Jwt generateToken(JwtUserInfo jwtUserInfo) {
return Jwt.builder()
.accessToken(jwtUtil.generateAccessToken(jwtUserInfo))
.refreshToken(jwtUtil.generateRefreshToken(jwtUserInfo))
.build();
}


}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kcy.fitapet.global.common.security.oauth;

import com.kcy.fitapet.global.common.security.oauth.dto.OIDCPublicKeyResponse;
import org.springframework.cloud.openfeign.FeignClient;

public interface OauthClient {
OIDCPublicKeyResponse getOIDCPublicKey();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.kcy.fitapet.global.common.security.oauth.dto.OIDCDecodePayload;
import org.springframework.stereotype.Component;

@Component
public interface OauthOIDCProvider {
/**
* ID Token의 header에서 kid를 추출하는 메서드
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.kcy.fitapet.global.common.security.jwt.exception.JwtErrorCodeUtil;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.security.Key;
Expand All @@ -16,6 +17,7 @@
import java.util.Base64;

@Slf4j
@Component
public class OauthOIDCProviderImpl implements OauthOIDCProvider {
private final String KID = "kid";
private final String RSA = "RSA";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.kcy.fitapet.global.common.security.oauth.OauthApplicationConfig;
import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.stereotype.Component;
Expand All @@ -11,9 +12,10 @@
import java.util.List;

@Getter
@Setter
@Validated
@Component
@ConfigurationProperties(prefix = "kakao")
@ConfigurationProperties(prefix = "oauth2.client.provider.kakao")
@ConfigurationPropertiesBinding
public class KakaoApplicationConfig implements OauthApplicationConfig {
@NotEmpty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

@FeignClient(
name = "KakaoOauthClient",
url = "${security.oauth2.client.provider.authorization-uri}",
url = "${oauth2.client.provider.kakao.authorization-uri}",
configuration = KakaoOauthConfig.class
)
public interface KakaoOauthClient extends OauthClient {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/kcy/fitapet/global/config/FeignConfig.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.kcy.fitapet.global.config;

import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableFeignClients(basePackages = "com.kcy.fitapet")
@ImportAutoConfiguration({FeignAutoConfiguration.class, HttpClientConfiguration.class})
public class FeignConfig {
}
26 changes: 26 additions & 0 deletions src/main/java/com/kcy/fitapet/global/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.kcy.fitapet.global.config;

import com.kcy.fitapet.global.common.redis.sms.SmsCertification;
import com.kcy.fitapet.global.config.feign.OidcCacheManager;
import com.kcy.fitapet.global.config.feign.RedisCacheConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
Expand All @@ -21,13 +25,34 @@

@Configuration
@EnableRedisRepositories
@EnableCaching
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;

@Bean
@Primary
public CacheManager redisCacheManager(
@RedisCacheConnectionFactory RedisConnectionFactory cf) {
RedisCacheConfiguration redisCacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new StringRedisSerializer()))
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()))
.entryTtl(Duration.ofHours(1L));

return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(cf)
.cacheDefaults(redisCacheConfiguration)
.build();
}

@Bean
@RedisCacheConnectionFactory
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, port);
// config.setPassword(); // redis 패스워드 설정 시, 주석 해제
Expand All @@ -46,6 +71,7 @@ public RedisTemplate<String, SmsCertification> redisTemplate() {
}

@Bean
@OidcCacheManager
public CacheManager oidcCacheManger(RedisConnectionFactory cf) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.kcy.fitapet.global.config.feign;

import org.springframework.beans.factory.annotation.Qualifier;

import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD,
ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Qualifier("oidcCacheManager")
public @interface OidcCacheManager {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.kcy.fitapet.global.config.feign;

import org.springframework.beans.factory.annotation.Qualifier;

import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD,
ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Qualifier("redisCacheConnectionFactory")
public @interface RedisCacheConnectionFactory {
}
27 changes: 12 additions & 15 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,18 @@ spring:
resources:
add-mappings: false

security:
oauth2:
client:
provider:
kakao:
authorization-uri: ${KAKAO_AUTH_URI}
registration:
kakao:
client-id: ${KAKAO_CLIENT_ID}
client-secret: ${KAKAO_CLIENT_SECRET}
client-name: Kakao
scope:
- profile_nickname
- profile_image
- account_email
oauth2:
client:
provider:
kakao:
authorization-uri: ${KAKAO_AUTH_URI}
client-id: ${KAKAO_CLIENT_ID}
client-secret: ${KAKAO_CLIENT_SECRET}
client-name: Kakao
scope:
- profile_nickname
- profile_image
- account_email


feign:
Expand Down

0 comments on commit 1c1af45

Please sign in to comment.