-
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.
카카오 회원가입/로그인, /api/auth/member API 기능 추가 (#6)
* ✨ 카카오 로그인/회원가입 구현 (#3) * Style: codeStyle 추가 * Feat: Member, Profile Entity, MemberRepository 추가 + MemberRepositoryTest 추가 Related to: #1 * Feat: 카카오 로그인, 회원가입 기능 추가 - 권한 필요한 API 접속 시 카카오 로그인 페이지 반환 - 로그인 성공 시 가입이 안되어있으면 가입, 되어있으면 권한 부여 - 권한은 JWT 발급 후 쿠키에 추가, 매 요청마다 JwtFilter를 거치며 쿠키의 Jwt 확 Related to: #1 * Style: 코드 포맷, 비밀번호 노출 등 수정 Related to: #1 * ✨ /api/auth/member API 기능 추가 (#4) * Feat: Member DB 수정 - 한글이름, 영어이름, 기수, 과정 추가 - 과정 표현하는 Enumerate 추가 - 수정에 따른 오류 수정 - getNickname -> getKoreaName of getEnglishName Related to: #2 * Rename: Member DB Field 이름 변경 Related to: #2 * Feat: /api/auth/member 관련 DTO 작성 Related to: #2 * Feat: /api/auth/member API 관련 DTO 내용 추가 Related to: #2 * Feat: /api/auth/member 관련 MemberService 추가 Related to: #2 * Feat: /api/auth/member 관련 MemberContoller 추가 Related to: #2 * Feat: CORS Error 수정 Related to: #2 * Fix: RefreshToken 매번 생성 오류 수정 Related to: #2 * Refactor: 코드 리뷰 내용 반영 - 불필요 코드 삭제 - 반환값 오류 수정 Related to: #2 * Chore: DB를 MariaDB -> H2로 변경 Ralted to: #5 * Test: Test용 application 추가 Related to: #5
- Loading branch information
1 parent
57b7065
commit 34f06b0
Showing
35 changed files
with
1,104 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 'com.h2database:h2' | ||
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,63 @@ | ||
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 org.springframework.web.cors.CorsConfiguration; | ||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | ||
import org.springframework.web.filter.CorsFilter; | ||
|
||
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(); | ||
} | ||
|
||
@Bean | ||
public CorsFilter corsFilter() { | ||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); | ||
CorsConfiguration config = new CorsConfiguration(); | ||
config.setAllowCredentials(true); | ||
config.addAllowedOriginPattern("*"); // 모든 도메인 허용. 필요에 따라 변경 | ||
config.addAllowedHeader("*"); | ||
config.addAllowedMethod("*"); | ||
source.registerCorsConfiguration("/**", config); | ||
return new CorsFilter(source); | ||
} | ||
} |
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() + " 님 환영합니다."; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/kaboo/kaboo_auth/controller/MainControllerAdvice.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,26 @@ | ||
package kaboo.kaboo_auth.controller; | ||
|
||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
|
||
import kaboo.kaboo_auth.domain.dto.response.ResponseDTO; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Slf4j | ||
@RestControllerAdvice | ||
public class MainControllerAdvice { | ||
|
||
@ExceptionHandler({IllegalStateException.class, UsernameNotFoundException.class}) | ||
public ResponseEntity<ResponseDTO<?>> exceptionHandler(Exception e) { | ||
log.error("[Kaboo-Auth]: 예외가 발생하였습니다. {}", e.getMessage()); | ||
return ResponseEntity.status(HttpStatus.OK) | ||
.body(new ResponseDTO<>( | ||
true, | ||
e.getMessage(), | ||
null | ||
)); | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
src/main/java/kaboo/kaboo_auth/controller/MemberController.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,86 @@ | ||
package kaboo.kaboo_auth.controller; | ||
|
||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import kaboo.kaboo_auth.domain.dto.request.MemberInfoUpdateRequest; | ||
import kaboo.kaboo_auth.domain.dto.response.MemberInfoResponse; | ||
import kaboo.kaboo_auth.domain.dto.response.MemberListResponse; | ||
import kaboo.kaboo_auth.domain.dto.response.ResponseDTO; | ||
import kaboo.kaboo_auth.service.MemberService; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api/auth/member") | ||
public class MemberController { | ||
|
||
private final MemberService memberService; | ||
|
||
@GetMapping("/all") | ||
public ResponseEntity<ResponseDTO<MemberListResponse>> getAllMembers() { | ||
return ResponseEntity.status(HttpStatus.OK) | ||
.body(new ResponseDTO<>( | ||
memberService.getAllMembers() | ||
)); | ||
} | ||
|
||
@GetMapping("/class/{class}") | ||
public ResponseEntity<ResponseDTO<MemberListResponse>> getClassMembers( | ||
@PathVariable(name = "class") int classNum) { | ||
|
||
return ResponseEntity.status(HttpStatus.OK) | ||
.body(new ResponseDTO<>( | ||
memberService.getMembersByClassNum(classNum) | ||
)); | ||
} | ||
|
||
@GetMapping | ||
public ResponseEntity<ResponseDTO<MemberInfoResponse>> getMemberInfo( | ||
@RequestParam(name = "name", defaultValue = "") String koreaName) { | ||
|
||
return ResponseEntity.status(HttpStatus.OK) | ||
.body(new ResponseDTO<>( | ||
memberService.getMemberInfoByKoreaName(koreaName) | ||
)); | ||
} | ||
|
||
@PostMapping | ||
public ResponseEntity<ResponseDTO<MemberInfoResponse>> updateMemberInfo( | ||
@RequestParam(name = "name", defaultValue = "") String koreaName, | ||
@RequestBody MemberInfoUpdateRequest request) { | ||
|
||
return ResponseEntity.status(HttpStatus.OK) | ||
.body(new ResponseDTO<>( | ||
memberService.updateMemberInfoByKoreaName(koreaName, request) | ||
)); | ||
} | ||
|
||
@GetMapping("/introduce") | ||
public ResponseEntity<ResponseDTO<String>> getMemberIntroduce( | ||
@RequestParam(name = "name", defaultValue = "") String koreaName) { | ||
|
||
return ResponseEntity.status(HttpStatus.OK) | ||
.body(new ResponseDTO<>( | ||
memberService.getMemberIntroduceByKoreaName(koreaName) | ||
)); | ||
} | ||
|
||
@PostMapping("/introduce") | ||
public ResponseEntity<ResponseDTO<String>> updateMemberIntrouce( | ||
@RequestParam(name = "name", defaultValue = "") String koreaName, | ||
@RequestBody String request) { | ||
|
||
return ResponseEntity.status(HttpStatus.OK) | ||
.body(new ResponseDTO<>( | ||
memberService.updateMemberIntroduceByKoreaName(koreaName, request) | ||
)); | ||
} | ||
} |
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,13 @@ | ||
package kaboo.kaboo_auth.domain; | ||
|
||
public enum Course { | ||
AI("GenAI"), | ||
FULLSTACK("Fullstack"), | ||
CLOUD("Cloud"); | ||
|
||
private final String course; | ||
|
||
Course(String course) { | ||
this.course = course; | ||
} | ||
} |
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.getKoreaName(); | ||
} | ||
|
||
@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; | ||
} | ||
} |
Oops, something went wrong.