forked from kookmin-sw/cap-template
-
Notifications
You must be signed in to change notification settings - Fork 1
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 kookmin-sw#5 from capstone-maru/feat/kookmin-sw#2-…
…OAuthKakao Feat/kookmin-sw#2 o auth kakao
- Loading branch information
Showing
16 changed files
with
900 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.capstone.maru.config; | ||
|
||
import java.util.Optional; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.domain.AuditorAware; | ||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing; | ||
|
||
@EnableJpaAuditing | ||
@Configuration | ||
public class JpaConfig { | ||
|
||
@Bean | ||
public AuditorAware<String> auditorAware() { | ||
return () -> Optional.of("tester"); | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
src/main/java/org/capstone/maru/config/SecurityConfig.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,94 @@ | ||
package org.capstone.maru.config; | ||
|
||
|
||
import org.capstone.maru.dto.security.KakaoOAuth2Response; | ||
import org.capstone.maru.dto.security.SharedPostPrincipal; | ||
import org.capstone.maru.service.MemberAccountService; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.boot.autoconfigure.security.servlet.PathRequest; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; | ||
import org.springframework.security.crypto.factory.PasswordEncoderFactories; | ||
import org.springframework.security.crypto.password.PasswordEncoder; | ||
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; | ||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; | ||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; | ||
import org.springframework.security.oauth2.core.user.OAuth2User; | ||
import org.springframework.security.web.SecurityFilterChain; | ||
|
||
@Configuration | ||
public class SecurityConfig { | ||
|
||
@Bean | ||
@ConditionalOnProperty(name = "spring.h2.console.enabled", havingValue = "true") | ||
public WebSecurityCustomizer configureH2ConsoleEnable() { | ||
return web -> web.ignoring() | ||
.requestMatchers(PathRequest.toH2Console()); | ||
} | ||
|
||
@Bean | ||
public SecurityFilterChain securityFilterChain( | ||
HttpSecurity httpSecurity, | ||
OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService | ||
) throws Exception { | ||
return httpSecurity | ||
.authorizeHttpRequests(auth -> auth | ||
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() | ||
.requestMatchers( | ||
HttpMethod.GET, | ||
"/" | ||
).permitAll() | ||
.anyRequest().authenticated() | ||
) | ||
.oauth2Login(oAuth -> oAuth | ||
.userInfoEndpoint(userInfo -> userInfo | ||
.userService(oAuth2UserService)) | ||
) | ||
.csrf( | ||
csrf -> csrf | ||
.ignoringRequestMatchers("/api/**") | ||
) | ||
.build(); | ||
} | ||
|
||
|
||
@Bean | ||
public OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService( | ||
MemberAccountService memberAccountService, | ||
PasswordEncoder passwordEncoder | ||
) { | ||
final DefaultOAuth2UserService delegate = new DefaultOAuth2UserService(); | ||
|
||
return userRequest -> { | ||
OAuth2User oAuth2User = delegate.loadUser(userRequest); | ||
|
||
KakaoOAuth2Response kakaoOAuthResponse = KakaoOAuth2Response.from( | ||
oAuth2User.getAttributes()); | ||
String registrationId = userRequest.getClientRegistration() | ||
.getRegistrationId(); // "kakao" | ||
String providerId = String.valueOf(kakaoOAuthResponse.id()); | ||
String userId = registrationId + "_" + providerId; | ||
|
||
return memberAccountService | ||
.searchMember(userId) | ||
.map(SharedPostPrincipal::from) | ||
.orElseGet(() -> | ||
SharedPostPrincipal.from( | ||
memberAccountService.saveUser( | ||
userId, | ||
kakaoOAuthResponse.email(), | ||
kakaoOAuthResponse.nickname() | ||
) | ||
) | ||
); | ||
}; | ||
} | ||
|
||
@Bean | ||
public PasswordEncoder passwordEncoder() { | ||
return PasswordEncoderFactories.createDelegatingPasswordEncoder(); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/org/capstone/maru/controller/MainController.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,20 @@ | ||
package org.capstone.maru.controller; | ||
|
||
import org.capstone.maru.dto.security.SharedPostPrincipal; | ||
import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
public class MainController { | ||
|
||
@GetMapping("/") | ||
public String root() { | ||
return "home"; | ||
} | ||
|
||
@GetMapping("/test") | ||
public String test(@AuthenticationPrincipal SharedPostPrincipal sharedPostPrincipal) { | ||
return sharedPostPrincipal.getName(); | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/java/org/capstone/maru/domain/AuditingFields.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,39 @@ | ||
package org.capstone.maru.domain; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.EntityListeners; | ||
import jakarta.persistence.MappedSuperclass; | ||
import java.time.LocalDateTime; | ||
import lombok.Getter; | ||
import lombok.ToString; | ||
import org.springframework.data.annotation.CreatedBy; | ||
import org.springframework.data.annotation.CreatedDate; | ||
import org.springframework.data.annotation.LastModifiedBy; | ||
import org.springframework.data.annotation.LastModifiedDate; | ||
import org.springframework.data.jpa.domain.support.AuditingEntityListener; | ||
import org.springframework.format.annotation.DateTimeFormat; | ||
|
||
@Getter | ||
@ToString(callSuper = true) | ||
@MappedSuperclass | ||
@EntityListeners(AuditingEntityListener.class) | ||
public class AuditingFields { | ||
|
||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) | ||
@CreatedDate | ||
@Column(nullable = false) | ||
protected LocalDateTime createdAt; // 생성일시 | ||
|
||
@CreatedBy | ||
@Column(nullable = false, updatable = false, length = 100) | ||
protected String createdBy; // 생성자 | ||
|
||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) | ||
@LastModifiedDate | ||
@Column(nullable = false) | ||
protected LocalDateTime modifiedAt; // 수정일시 | ||
|
||
@LastModifiedBy | ||
@Column(nullable = false, length = 100) | ||
protected String modifiedBy; // 수정자 | ||
} |
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,84 @@ | ||
package org.capstone.maru.domain; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Index; | ||
import jakarta.persistence.Table; | ||
import java.util.Objects; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import lombok.ToString; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@ToString(callSuper = true) | ||
@Table(indexes = { | ||
@Index(columnList = "memberId", unique = true), | ||
@Index(columnList = "email", unique = true), | ||
@Index(columnList = "createdAt"), | ||
@Index(columnList = "createdBy") | ||
}) | ||
@Entity | ||
public class MemberAccount extends AuditingFields { | ||
|
||
@Id | ||
@Column(nullable = false, length = 50) | ||
private String memberId; | ||
|
||
@Setter | ||
@Column(length = 100) | ||
private String email; | ||
|
||
@Setter | ||
@Column(length = 100) | ||
private String nickname; | ||
|
||
private MemberAccount( | ||
String memberId, | ||
String email, | ||
String nickname, | ||
String createdBy | ||
) { | ||
this.memberId = memberId; | ||
this.email = email; | ||
this.nickname = nickname; | ||
this.createdBy = createdBy; | ||
this.modifiedBy = createdBy; | ||
} | ||
|
||
public static MemberAccount of( | ||
String memberId, | ||
String email, | ||
String nickname | ||
) { | ||
return new MemberAccount(memberId, email, nickname, null); | ||
} | ||
|
||
public static MemberAccount of( | ||
String memberId, | ||
String email, | ||
String nickname, | ||
String createdBy | ||
) { | ||
return new MemberAccount(memberId, email, nickname, createdBy); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (!(o instanceof MemberAccount that)) { | ||
return false; | ||
} | ||
return this.getMemberId() != null && this.getMemberId().equals(that.getMemberId()); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(this.getMemberId()); | ||
} | ||
} |
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,72 @@ | ||
package org.capstone.maru.dto; | ||
|
||
import java.time.LocalDateTime; | ||
import org.capstone.maru.domain.MemberAccount; | ||
|
||
public record MemberAccountDto( | ||
String memberId, | ||
String email, | ||
String nickname, | ||
LocalDateTime createdAt, | ||
String createdBy, | ||
LocalDateTime modifiedAt, | ||
String modifiedBy | ||
) { | ||
|
||
public static MemberAccountDto of( | ||
String memberId, | ||
String email, | ||
String nickname | ||
) { | ||
return new MemberAccountDto( | ||
memberId, | ||
email, | ||
nickname, | ||
null, | ||
null, | ||
null, | ||
null | ||
); | ||
} | ||
|
||
public static MemberAccountDto of( | ||
String memberId, | ||
String email, | ||
String nickname, | ||
LocalDateTime createdAt, | ||
String createdBy, | ||
LocalDateTime modifiedAt, | ||
String modifiedBy | ||
) { | ||
return new MemberAccountDto( | ||
memberId, | ||
email, | ||
nickname, | ||
createdAt, | ||
createdBy, | ||
modifiedAt, | ||
modifiedBy | ||
); | ||
} | ||
|
||
public static MemberAccountDto from(MemberAccount entity) { | ||
return new MemberAccountDto( | ||
entity.getMemberId(), | ||
entity.getEmail(), | ||
entity.getNickname(), | ||
entity.getCreatedAt(), | ||
entity.getCreatedBy(), | ||
entity.getModifiedAt(), | ||
entity.getModifiedBy() | ||
); | ||
} | ||
|
||
public MemberAccount toEntity() { | ||
return MemberAccount.of( | ||
memberId, | ||
email, | ||
nickname, | ||
createdBy | ||
); | ||
} | ||
} |
Oops, something went wrong.