Skip to content

Commit

Permalink
feat naver config
Browse files Browse the repository at this point in the history
  • Loading branch information
cheesecrust committed Mar 8, 2024
1 parent d022adc commit a349d85
Show file tree
Hide file tree
Showing 14 changed files with 305 additions and 10 deletions.
19 changes: 13 additions & 6 deletions src/main/java/org/capstone/maru/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.capstone.maru.config;


import lombok.extern.slf4j.Slf4j;
import org.capstone.maru.dto.security.KakaoOAuth2Response;
import org.capstone.maru.dto.security.SharedPostPrincipal;
import org.capstone.maru.service.MemberAccountService;
Expand All @@ -19,21 +20,23 @@
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.SecurityFilterChain;

@Slf4j
@Configuration
public class SecurityConfig {

@Bean
@ConditionalOnProperty(name = "spring.h2.console.enabled", havingValue = "true")
public WebSecurityCustomizer configureH2ConsoleEnable() {
return web -> web.ignoring()
.requestMatchers(PathRequest.toH2Console());
.requestMatchers(PathRequest.toH2Console());
}

@Bean
public SecurityFilterChain securityFilterChain(
HttpSecurity httpSecurity,
OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService
) throws Exception {
log.info("SecurityFilterChain 빈 등록 완료");
return httpSecurity
.authorizeHttpRequests(auth -> auth
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
Expand All @@ -45,11 +48,13 @@ public SecurityFilterChain securityFilterChain(
)
.oauth2Login(oAuth -> oAuth
.userInfoEndpoint(userInfo -> userInfo
.userService(oAuth2UserService))
.userService(oAuth2UserService)
)
)
.csrf(
csrf -> csrf
.ignoringRequestMatchers("/api/**")
.disable()
)
.build();
}
Expand All @@ -67,18 +72,20 @@ public OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService(

KakaoOAuth2Response kakaoOAuthResponse = KakaoOAuth2Response.from(
oAuth2User.getAttributes());

String registrationId = userRequest.getClientRegistration()
.getRegistrationId(); // "kakao"
.getRegistrationId(); // "kakao"

String providerId = String.valueOf(kakaoOAuthResponse.id());
String userId = registrationId + "_" + providerId;
String memberId = registrationId + "_" + providerId;

return memberAccountService
.searchMember(userId)
.searchMember(memberId)
.map(SharedPostPrincipal::from)
.orElseGet(() ->
SharedPostPrincipal.from(
memberAccountService.saveUser(
userId,
memberId,
kakaoOAuthResponse.email(),
kakaoOAuthResponse.nickname()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ public String root() {
public String test(@AuthenticationPrincipal SharedPostPrincipal sharedPostPrincipal) {
return sharedPostPrincipal.getName();
}

}
16 changes: 13 additions & 3 deletions src/main/java/org/capstone/maru/domain/MemberAccount.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
import jakarta.persistence.Table;
import java.util.Objects;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.capstone.maru.dto.Role;
import org.capstone.maru.dto.SocialType;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -36,25 +39,32 @@ public class MemberAccount extends AuditingFields {
@Column(length = 100)
private String nickname;

private SocialType socialType;

private Role role;

@Builder
private MemberAccount(
String memberId,
String email,
String nickname,
String createdBy
String createdBy,
SocialType socialType
) {
this.memberId = memberId;
this.email = email;
this.nickname = nickname;
this.createdBy = createdBy;
this.modifiedBy = createdBy;
this.socialType = socialType;
}

public static MemberAccount of(
String memberId,
String email,
String nickname
) {
return new MemberAccount(memberId, email, nickname, null);
return new MemberAccount(memberId, email, nickname, null, null);
}

public static MemberAccount of(
Expand All @@ -63,7 +73,7 @@ public static MemberAccount of(
String nickname,
String createdBy
) {
return new MemberAccount(memberId, email, nickname, createdBy);
return new MemberAccount(memberId, email, nickname, createdBy, null);
}

@Override
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/org/capstone/maru/dto/CustomOAuth2User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.capstone.maru.dto;

import java.util.Collection;
import java.util.Map;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;

public class CustomOAuth2User extends DefaultOAuth2User {

public CustomOAuth2User(Collection<? extends GrantedAuthority> authorities,
Map<String, Object> attributes, String nameAttributeKey, String email) {
super(authorities, attributes, nameAttributeKey);
}
}
21 changes: 21 additions & 0 deletions src/main/java/org/capstone/maru/dto/KakaoOAuth2UserInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.capstone.maru.dto;

import java.util.Map;

public class KakaoOAuth2UserInfo extends OAuth2UserInfo {

public KakaoOAuth2UserInfo(Map<String, Object> attributes) {
super(attributes);
}

@Override
public String getId() {
return String.valueOf(attributes.get("id"));
}

@Override
public String getNickname() {
return null;
}

}
20 changes: 20 additions & 0 deletions src/main/java/org/capstone/maru/dto/NaverOAuth2UserInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.capstone.maru.dto;

import java.util.Map;

public class NaverOAuth2UserInfo extends OAuth2UserInfo {

public NaverOAuth2UserInfo(Map<String, Object> attributes) {
super(attributes);
}

@Override
public String getId() {
return String.valueOf(attributes.get("id"));
}

@Override
public String getNickname() {
return null;
}
}
17 changes: 17 additions & 0 deletions src/main/java/org/capstone/maru/dto/OAuth2UserInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.capstone.maru.dto;

import java.util.Map;

public abstract class OAuth2UserInfo {

protected Map<String, Object> attributes;

public OAuth2UserInfo(Map<String, Object> attributes) {
this.attributes = attributes;
}

public abstract String getId(); //소셜 식별 값 : 구글 - "sub", 카카오 - "id", 네이버 - "id"

public abstract String getNickname();

}
65 changes: 65 additions & 0 deletions src/main/java/org/capstone/maru/dto/OAuthAttributes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.capstone.maru.dto;

import java.util.Map;
import lombok.Builder;
import lombok.Getter;
import org.capstone.maru.domain.MemberAccount;

@Getter
public class OAuthAttributes {

private String nameAttributeKey; // OAuth2 로그인 진행 시 키가 되는 필드 값, PK와 같은 의미
private OAuth2UserInfo oauth2UserInfo; // 소셜 타입별 로그인 유저 정보(닉네임, 이메일, 프로필 사진 등등)

@Builder
public OAuthAttributes(String nameAttributeKey, OAuth2UserInfo oauth2UserInfo) {
this.nameAttributeKey = nameAttributeKey;
this.oauth2UserInfo = oauth2UserInfo;
}

/**
* SocialType에 맞는 메소드 호출하여 OAuthAttributes 객체 반환 파라미터 : userNameAttributeName -> OAuth2 로그인 시
* 키(PK)가 되는 값 / attributes : OAuth 서비스의 유저 정보들 소셜별 of 메소드(ofGoogle, ofKaKao, ofNaver)들은 각각 소셜
* 로그인 API에서 제공하는 회원의 식별값(id), attributes, nameAttributeKey를 저장 후 build
*/
public static OAuthAttributes of(SocialType socialType,
String userNameAttributeName, Map<String, Object> attributes) {

if (socialType == SocialType.NAVER) {
return ofNaver(userNameAttributeName, attributes);
}
if (socialType == SocialType.KAKAO) {
return ofKakao(userNameAttributeName, attributes);
}
return null;
}

private static OAuthAttributes ofKakao(String userNameAttributeName,
Map<String, Object> attributes) {
return OAuthAttributes.builder()
.nameAttributeKey(userNameAttributeName)
.oauth2UserInfo(new KakaoOAuth2UserInfo(attributes))
.build();
}

public static OAuthAttributes ofNaver(String userNameAttributeName,
Map<String, Object> attributes) {
return OAuthAttributes.builder()
.nameAttributeKey(userNameAttributeName)
.oauth2UserInfo(new NaverOAuth2UserInfo(attributes))
.build();
}

/**
* of메소드로 OAuthAttributes 객체가 생성되어, 유저 정보들이 담긴 OAuth2UserInfo가 소셜 타입별로 주입된 상태 OAuth2UserInfo에서
* socialId(식별값), nickname을 가져와서 build
*/
public MemberAccount toEntity(SocialType socialType, OAuth2UserInfo oauth2UserInfo) {
return MemberAccount.builder()
.memberId(oauth2UserInfo.getId())
.nickname(oauth2UserInfo.getNickname())
.socialType(socialType)
.build();
}

}
14 changes: 14 additions & 0 deletions src/main/java/org/capstone/maru/dto/Role.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.capstone.maru.dto;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum Role {

GUEST("ROLE_GUEST"), USER("ROLE_USER");

private final String key;
}

5 changes: 5 additions & 0 deletions src/main/java/org/capstone/maru/dto/SocialType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.capstone.maru.dto;

public enum SocialType {
KAKAO, NAVER
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public record SharedPostPrincipal(
Map<String, Object> oAuth2Attributes
) implements UserDetails, OAuth2User {

/**
* of 파라미터를 받아서 현제 객체를 리턴합니다.
*
* @param memberId
* @param email
* @param nickname
* @return
*/
public static SharedPostPrincipal of(
String memberId,
String email,
Expand Down Expand Up @@ -48,6 +56,12 @@ public static SharedPostPrincipal of(
);
}

/**
* MemberAccountDto를 받아서 현재 객체를 리턴합니다.
*
* @param dto
* @return
*/
public static SharedPostPrincipal from(MemberAccountDto dto) {
return SharedPostPrincipal.of(
dto.memberId(),
Expand All @@ -56,6 +70,11 @@ public static SharedPostPrincipal from(MemberAccountDto dto) {
);
}

/**
* 현재 객체를 dto로 바꿔줍니다
*
* @return
*/
public MemberAccountDto toDto() {
return MemberAccountDto.of(
memberId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package org.capstone.maru.repository;

import java.util.Optional;
import org.capstone.maru.domain.MemberAccount;
import org.capstone.maru.dto.SocialType;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberAccountRepository extends JpaRepository<MemberAccount, String> {

Optional<MemberAccount> findBySocialTypeAndSocialId(SocialType socialType, String id);
}
Loading

0 comments on commit a349d85

Please sign in to comment.