-
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 #14 from 2024-Iris/auth
Authentication 구현 및 테스트 코드 작성
- Loading branch information
Showing
28 changed files
with
766 additions
and
43 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
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,5 +1,6 @@ | ||
.gradle | ||
.idea/** | ||
**/main/**/application.yml | ||
build/ | ||
!gradle/wrapper/gradle-wrapper.jar | ||
!**/src/main/**/build/ | ||
|
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
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
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 site.iris.issuefy.config; | ||
|
||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.servlet.config.annotation.CorsRegistry; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
@Configuration | ||
public class CorsConfig implements WebMvcConfigurer { | ||
|
||
@Override | ||
public void addCorsMappings(CorsRegistry registry) { | ||
registry.addMapping("/api/**") // CORS를 적용할 URL 패턴 설정 | ||
.allowedOrigins("http://localhost:3000") // 허용할 Origin 설정 | ||
.allowedMethods("GET", "POST", "PUT", "DELETE") // 허용할 HTTP 메서드 설정 | ||
.allowedHeaders("*"); // 허용할 HTTP 헤더 설정 | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/site/iris/issuefy/config/WebClientConfig.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,25 @@ | ||
package site.iris.issuefy.config; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.reactive.function.client.WebClient; | ||
|
||
@Configuration | ||
public class WebClientConfig { | ||
|
||
@Bean(name = "apiWebClient") | ||
public WebClient apiWebClient() { | ||
return WebClient.builder() | ||
.baseUrl("https://api.github.com/") | ||
.build(); | ||
} | ||
|
||
@Bean(name = "accessTokenWebClient") | ||
public WebClient accessTokenWebClient() { | ||
return WebClient.builder() | ||
.baseUrl("https://github.com/") | ||
.build(); | ||
} | ||
} | ||
|
||
|
27 changes: 27 additions & 0 deletions
27
src/main/java/site/iris/issuefy/controller/AuthenticationController.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,27 @@ | ||
package site.iris.issuefy.controller; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import site.iris.issuefy.dto.OauthResponse; | ||
import site.iris.issuefy.service.AuthenticationService; | ||
import site.iris.issuefy.vo.UserDto; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequiredArgsConstructor | ||
public class AuthenticationController { | ||
private final AuthenticationService authenticationService; | ||
|
||
@GetMapping("/api/login") | ||
public ResponseEntity<OauthResponse> login(@RequestParam String code) { | ||
UserDto userDto = authenticationService.githubLogin(code); | ||
String tempJWT = "RETURNTESTJWT"; | ||
return ResponseEntity.ok() | ||
.body(OauthResponse.of(userDto.getLogin(), userDto.getAvatar_url(), tempJWT)); | ||
} | ||
} |
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,16 @@ | ||
package site.iris.issuefy.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Data; | ||
|
||
@Data | ||
@AllArgsConstructor | ||
public class OauthResponse { | ||
private String userName; | ||
private String avatarURL; | ||
private String JWT; | ||
|
||
public static OauthResponse of(String userName, String avatarURL, String JWT) { | ||
return new OauthResponse(userName, avatarURL, JWT); | ||
} | ||
} |
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,18 @@ | ||
package site.iris.issuefy.entity; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public class Jwt { | ||
private final String accessToken; | ||
private final String refreshToken; | ||
|
||
private Jwt(String accessToken, String refreshToken) { | ||
this.accessToken = accessToken; | ||
this.refreshToken = refreshToken; | ||
} | ||
|
||
public static Jwt of(String accessToken, String refreshToken) { | ||
return new Jwt(accessToken, refreshToken); | ||
} | ||
} |
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,7 @@ | ||
package site.iris.issuefy.entity; | ||
|
||
public class User { | ||
private Long id; | ||
private String nickname; | ||
private String avatarUrl; | ||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/site/iris/issuefy/repository/UserRepository.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,13 @@ | ||
package site.iris.issuefy.repository; | ||
|
||
import org.springframework.stereotype.Repository; | ||
|
||
import site.iris.issuefy.entity.User; | ||
|
||
@Repository | ||
public class UserRepository { | ||
|
||
public User findByNickname(String nickname) { | ||
return new User(); | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
src/main/java/site/iris/issuefy/service/AuthenticationService.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,78 @@ | ||
package site.iris.issuefy.service; | ||
|
||
import java.util.Collections; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.ConcurrentMap; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.reactive.function.client.WebClient; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import site.iris.issuefy.vo.OauthDto; | ||
import site.iris.issuefy.vo.UserDto; | ||
|
||
@Slf4j | ||
@Service | ||
public class AuthenticationService { | ||
|
||
private static final int KEY_INDEX = 0; | ||
private static final int VALUE_INDEX = 1; | ||
private static final int REQUIRE_SIZE = 2; | ||
private final GithubAccessTokenService githubAccessTokenService; | ||
private final WebClient webClient; | ||
|
||
// 2개의 WebClient Bean중에서 apiWebClient Bean을 사용하기 위해 생성자를 만들었습니다. | ||
@Autowired | ||
public AuthenticationService(GithubAccessTokenService githubAccessTokenService, | ||
@Qualifier("apiWebClient") WebClient webClient) { | ||
this.githubAccessTokenService = githubAccessTokenService; | ||
this.webClient = webClient; | ||
} | ||
|
||
public UserDto githubLogin(String code) { | ||
String accessToken = githubAccessTokenService.getToken(code); | ||
log.info("accessToken : {}", accessToken); | ||
|
||
OauthDto oauthDto = parseOauthDto(accessToken); | ||
log.info(oauthDto.toString()); | ||
|
||
return getUserInfo(oauthDto); | ||
} | ||
|
||
private OauthDto parseOauthDto(String accessToken) { | ||
ConcurrentMap<String, String> responseMap = new ConcurrentHashMap<>(); | ||
String[] pair = accessToken.split("&"); | ||
|
||
for (String pairStr : pair) { | ||
String[] keyValue = pairStr.split("="); | ||
if (keyValue.length == REQUIRE_SIZE) { | ||
responseMap.put(keyValue[KEY_INDEX], keyValue[VALUE_INDEX]); | ||
} else { | ||
// null 값 대신 빈 문자열 | ||
responseMap.put(keyValue[KEY_INDEX], ""); | ||
} | ||
} | ||
|
||
// 필수 키가 없으면 예외 발생 | ||
if (!responseMap.containsKey("access_token") || !responseMap.containsKey("token_type")) { | ||
throw new IllegalArgumentException("Response does not contain all required keys"); | ||
} | ||
|
||
return OauthDto.fromMap(responseMap); | ||
} | ||
|
||
private UserDto getUserInfo(OauthDto oauthDto) { | ||
return webClient.get() | ||
.uri("/user") | ||
.headers(headers -> { | ||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); | ||
headers.setBearerAuth(oauthDto.getAccess_token()); | ||
}) | ||
.retrieve() | ||
.bodyToMono(UserDto.class) | ||
.block(); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/main/java/site/iris/issuefy/service/GithubAccessTokenService.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,34 @@ | ||
package site.iris.issuefy.service; | ||
|
||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.reactive.function.BodyInserters; | ||
import org.springframework.web.reactive.function.client.WebClient; | ||
|
||
@Service | ||
public class GithubAccessTokenService { | ||
|
||
private final WebClient webClient; | ||
@Value("${github.client-secret}") | ||
private String clientSecret; | ||
@Value("${github.client-id}") | ||
private String clientId; | ||
|
||
public GithubAccessTokenService(@Qualifier("accessTokenWebClient") WebClient webClient) { | ||
this.webClient = webClient; | ||
} | ||
|
||
public String getToken(String code) { | ||
return webClient.post() | ||
.uri("/login/oauth/access_token") | ||
.contentType(MediaType.APPLICATION_FORM_URLENCODED) | ||
.body(BodyInserters.fromFormData("client_id", clientId) | ||
.with("client_secret", clientSecret) | ||
.with("code", code)) | ||
.retrieve() | ||
.bodyToMono(String.class) | ||
.block(); | ||
} | ||
} |
Oops, something went wrong.