-
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.
* Style: codeStyle 추가 * Feat: Member, Profile Entity, MemberRepository 추가 + MemberRepositoryTest 추가 Related to: #1 * Feat: 카카오 로그인, 회원가입 기능 추가 - 권한 필요한 API 접속 시 카카오 로그인 페이지 반환 - 로그인 성공 시 가입이 안되어있으면 가입, 되어있으면 권한 부여 - 권한은 JWT 발급 후 쿠키에 추가, 매 요청마다 JwtFilter를 거치며 쿠키의 Jwt 확 Related to: #1 * Style: 코드 포맷, 비밀번호 노출 등 수정 Related to: #1
- Loading branch information
1 parent
57b7065
commit 90052aa
Showing
27 changed files
with
811 additions
and
23 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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,40 +1,47 @@ | ||
plugins { | ||
id 'java' | ||
id 'org.springframework.boot' version '3.3.2' | ||
id 'io.spring.dependency-management' version '1.1.6' | ||
id 'java' | ||
id 'org.springframework.boot' version '3.3.2' | ||
id 'io.spring.dependency-management' version '1.1.6' | ||
} | ||
|
||
group = 'kaboo' | ||
version = '0.0.1-SNAPSHOT' | ||
|
||
java { | ||
toolchain { | ||
languageVersion = JavaLanguageVersion.of(17) | ||
} | ||
toolchain { | ||
languageVersion = JavaLanguageVersion.of(17) | ||
} | ||
} | ||
|
||
configurations { | ||
compileOnly { | ||
extendsFrom annotationProcessor | ||
} | ||
compileOnly { | ||
extendsFrom annotationProcessor | ||
} | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' | ||
implementation 'org.springframework.boot:spring-boot-starter-security' | ||
implementation 'org.springframework.boot:spring-boot-starter-web' | ||
compileOnly 'org.projectlombok:lombok' | ||
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' | ||
annotationProcessor 'org.projectlombok:lombok' | ||
testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||
testImplementation 'org.springframework.security:spring-security-test' | ||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' | ||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' | ||
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' | ||
implementation 'org.springframework.boot:spring-boot-starter-security' | ||
implementation 'org.springframework.boot:spring-boot-starter-web' | ||
compileOnly 'org.projectlombok:lombok' | ||
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' | ||
annotationProcessor 'org.projectlombok:lombok' | ||
testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||
testImplementation 'org.springframework.security:spring-security-test' | ||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' | ||
|
||
// JWT Token Dependency | ||
implementation 'io.jsonwebtoken:jjwt-api:0.12.6' | ||
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' | ||
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6' | ||
implementation 'org.springframework.boot:spring-boot-starter-data-redis' | ||
} | ||
|
||
tasks.named('test') { | ||
useJUnitPlatform() | ||
useJUnitPlatform() | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/kaboo/kaboo_auth/config/PasswordEncoderConfig.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,14 @@ | ||
package kaboo.kaboo_auth.config; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
import org.springframework.security.crypto.password.PasswordEncoder; | ||
|
||
@Configuration | ||
public class PasswordEncoderConfig { | ||
@Bean | ||
public PasswordEncoder passwordEncoder() { | ||
return new BCryptPasswordEncoder(); | ||
} | ||
} |
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,48 @@ | ||
package kaboo.kaboo_auth.config; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; | ||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; | ||
import org.springframework.security.config.http.SessionCreationPolicy; | ||
import org.springframework.security.web.SecurityFilterChain; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
||
import kaboo.kaboo_auth.domain.handler.LoginSuccessHandler; | ||
import kaboo.kaboo_auth.domain.jwt.filter.JwtFilter; | ||
import kaboo.kaboo_auth.service.CustomOAuth2Service; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Configuration | ||
@EnableWebSecurity | ||
@RequiredArgsConstructor | ||
public class SecurityConfig { | ||
|
||
private final JwtFilter jwtFilter; | ||
private final CustomOAuth2Service customOAuth2Service; | ||
private final LoginSuccessHandler loginSuccessHandler; | ||
|
||
@Bean | ||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||
http | ||
.authorizeHttpRequests(auth -> auth | ||
.requestMatchers("/").permitAll() | ||
.anyRequest().authenticated()) // 그 외 요청은 인증 필요 | ||
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)); | ||
|
||
http | ||
.csrf(AbstractHttpConfigurer::disable) | ||
.formLogin(AbstractHttpConfigurer::disable) | ||
.httpBasic(AbstractHttpConfigurer::disable) | ||
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) | ||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); | ||
|
||
http.oauth2Login(auth -> auth | ||
.userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig.userService(customOAuth2Service)) | ||
.successHandler(loginSuccessHandler)); | ||
|
||
return http.build(); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/kaboo/kaboo_auth/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,24 @@ | ||
package kaboo.kaboo_auth.controller; | ||
|
||
import org.springframework.security.core.Authentication; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
public class MainController { | ||
|
||
@GetMapping("/") | ||
public String mainAPI() { | ||
return "누구나 접근가능한 API입니다."; | ||
} | ||
|
||
@GetMapping("/test") | ||
public String authAPI() { | ||
return "권한 Test API 입니다."; | ||
} | ||
|
||
@GetMapping("/auth/hello") | ||
public String helloAuth(Authentication authentication) { | ||
return "인가 받은 사용자 " + authentication.getName() + " 님 환영합니다."; | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/main/java/kaboo/kaboo_auth/domain/CustomUserDetails.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,45 @@ | ||
package kaboo.kaboo_auth.domain; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Map; | ||
|
||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
import org.springframework.security.oauth2.core.user.OAuth2User; | ||
|
||
import kaboo.kaboo_auth.domain.entity.Member; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@RequiredArgsConstructor | ||
public class CustomUserDetails implements OAuth2User, UserDetails { | ||
private final Member member; | ||
|
||
@Override | ||
public String getUsername() { | ||
return member.getUsername(); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return member.getNickname(); | ||
} | ||
|
||
@Override | ||
public String getPassword() { | ||
return member.getPassword(); | ||
} | ||
|
||
@Override | ||
public Map<String, Object> getAttributes() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public Collection<? extends GrantedAuthority> getAuthorities() { | ||
Collection<GrantedAuthority> collection = new ArrayList<>(); | ||
collection.add((GrantedAuthority)() -> member.getRole().toString()); | ||
|
||
return collection; | ||
} | ||
} |
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 kaboo.kaboo_auth.domain; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public enum UserRole { | ||
ROLE_ADMIN("ROLE_ADMIN"), | ||
ROLE_USER("ROLE_USER"); | ||
|
||
private final String role; | ||
|
||
UserRole(String role) { | ||
this.role = role; | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
src/main/java/kaboo/kaboo_auth/domain/dto/response/KakaoResponse.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,72 @@ | ||
package kaboo.kaboo_auth.domain.dto.response; | ||
|
||
import java.util.Map; | ||
|
||
/** Kakao Response 형태 | ||
* { | ||
* id: int, | ||
* connected_at: Date | ||
* properties: { | ||
* nickname: String | ||
* profile_image: URL | ||
* thumbnail_image: URL | ||
* }, | ||
* kakao_account: { | ||
* profile_nickname_needs_agreement: boolean, | ||
* profile_image_needs_agreement: boolean | ||
* profile: { | ||
* nickname: String | ||
* thumbnail_image_url: URL | ||
* profile_image_url: URL | ||
* is_default_image: boolean | ||
* is_default_nickname: boolean | ||
* }, | ||
* has_email=true, | ||
* email_needs_agreement=false, | ||
* is_email_valid=true, | ||
* is_email_verified=true, | ||
* [email protected] | ||
* } | ||
* | ||
* } | ||
*/ | ||
|
||
public class KakaoResponse implements OAuth2Response { | ||
private final Map<String, Object> attribute; | ||
|
||
public KakaoResponse(Map<String, Object> attribute) { | ||
this.attribute = attribute; | ||
} | ||
|
||
@Override | ||
public String getProvider() { | ||
return "kakao"; | ||
} | ||
|
||
@Override | ||
public String getProviderId() { | ||
return attribute.get("id").toString(); | ||
} | ||
|
||
@Override | ||
public String getEmail() { | ||
Map<String, Object> kakaoAccount = (Map<String, Object>)attribute.get("kakao_account"); | ||
|
||
// "kakao_account" 맵에서 "email" 키의 값을 가져옴 | ||
if (kakaoAccount != null && kakaoAccount.containsKey("email")) { | ||
return kakaoAccount.get("email").toString(); | ||
} | ||
return null; // email이 없을 경우 | ||
} | ||
|
||
@Override | ||
public String getNickname() { | ||
Map<String, Object> properties = (Map<String, Object>)attribute.get("properties"); | ||
|
||
// "properties" 맵에서 "nickname" 키의 값을 가져옴 | ||
if (properties != null && properties.containsKey("nickname")) { | ||
return properties.get("nickname").toString(); | ||
} | ||
return null; // nickname이 없을 경우 | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/kaboo/kaboo_auth/domain/dto/response/OAuth2Response.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,11 @@ | ||
package kaboo.kaboo_auth.domain.dto.response; | ||
|
||
public interface OAuth2Response { | ||
String getProvider(); | ||
|
||
String getProviderId(); | ||
|
||
String getEmail(); | ||
|
||
String getNickname(); | ||
} |
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,41 @@ | ||
package kaboo.kaboo_auth.domain.entity; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import kaboo.kaboo_auth.domain.UserRole; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@Getter | ||
@NoArgsConstructor | ||
public class Member { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "member_id") | ||
private Long id; | ||
|
||
private String username; | ||
private String email; | ||
private String nickname; | ||
private String password; | ||
private String info; | ||
|
||
@Enumerated(EnumType.STRING) | ||
private UserRole role; | ||
|
||
@Builder | ||
public Member(String username, String email, String nickname, String password, UserRole role) { | ||
this.username = username; | ||
this.email = email; | ||
this.nickname = nickname; | ||
this.password = password; | ||
this.role = role; | ||
} | ||
} |
Oops, something went wrong.