Skip to content

Commit

Permalink
refactor: 소셜로그인 redirect uri 경로 수정 (#50)
Browse files Browse the repository at this point in the history
* feat: 요청으로부터 origin 추출 로직 추가

* refactor: 요청 호스트에 따른 redirect_url 반환 적용

* chore: redirect_uri 수정
  • Loading branch information
TaeyeonRoyce authored Jan 26, 2024
1 parent 36293a8 commit 85919c9
Show file tree
Hide file tree
Showing 19 changed files with 192 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public interface OAuthClient {

String getSignInUrl();
String getSignInUrl(String host);

OAuthServiceType getOAuthService();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.baro.auth.application.oauth.dto.OAuthMemberInfo;
import com.baro.auth.application.oauth.dto.OAuthTokenInfo;
import com.baro.auth.domain.oauth.OAuthServiceType;

import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Component;
Expand All @@ -23,9 +22,9 @@ public OAuthInfoProvider(Set<OAuthClient> clients) {
.collect(toMap(OAuthClient::getOAuthService, identity()));
}

public String getSignInUrl(String oAuthService) {
public String getSignInUrl(String oAuthService, String host) {
OAuthClient client = getClient(oAuthService);
return client.getSignInUrl();
return client.getSignInUrl(host);
}

public OAuthMemberInfo getMemberInfo(String oAuthService, String code) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package com.baro.auth.infra.oauth.google;

import com.baro.auth.application.oauth.OAuthClient;
import com.baro.auth.application.oauth.dto.OAuthMemberInfo;
import com.baro.auth.application.oauth.dto.OAuthTokenInfo;
import com.baro.auth.domain.oauth.OAuthServiceType;
import com.baro.auth.infra.oauth.google.config.GoogleOAuthProperty;
import com.baro.auth.infra.oauth.google.dto.GoogleMemberResponse;
import com.baro.auth.infra.oauth.google.dto.GoogleTokenResponse;
import com.baro.auth.application.oauth.OAuthClient;
import java.util.LinkedHashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.LinkedHashMap;
import java.util.Map;

@RequiredArgsConstructor
@Component
public class GoogleOAuthClient implements OAuthClient {
Expand All @@ -22,12 +21,12 @@ public class GoogleOAuthClient implements OAuthClient {
private final GoogleRequestApi googleRequestApi;

@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return UriComponentsBuilder
.fromUriString(googleOAuthProperty.signInAuthorizeUrl())
.queryParam("client_id", googleOAuthProperty.clientId())
.queryParam("redirect_uri", googleOAuthProperty.redirectUri())
.queryParam("response_type", googleOAuthProperty.responseType())
.queryParam("redirect_uri", host + googleOAuthProperty.redirectUri())
.queryParam("scope", String.join(",", googleOAuthProperty.scope()))
.toUriString();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package com.baro.auth.infra.oauth.kakao;

import com.baro.auth.application.oauth.OAuthClient;
import com.baro.auth.application.oauth.dto.OAuthMemberInfo;
import com.baro.auth.application.oauth.dto.OAuthTokenInfo;
import com.baro.auth.domain.oauth.OAuthServiceType;
import com.baro.auth.infra.oauth.kakao.config.KakaoOAuthProperty;
import com.baro.auth.infra.oauth.kakao.dto.KakaoMemberResponse;
import com.baro.auth.infra.oauth.kakao.dto.KakaoTokenResponse;
import com.baro.auth.application.oauth.OAuthClient;

import java.util.LinkedHashMap;
import java.util.Map;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
Expand All @@ -23,12 +21,12 @@ public class KakaoOAuthClient implements OAuthClient {
private final KakaoRequestApi kakaoRequestApi;

@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return UriComponentsBuilder
.fromUriString(kakaoOAuthProperty.signInAuthorizeUrl())
.queryParam("response_type", kakaoOAuthProperty.responseType())
.queryParam("client_id", kakaoOAuthProperty.clientId())
.queryParam("redirect_uri", kakaoOAuthProperty.redirectUrl())
.queryParam("redirect_uri", host + kakaoOAuthProperty.redirectUri())
.queryParam("scope", String.join(",", kakaoOAuthProperty.scope()))
.toUriString();
}
Expand All @@ -38,7 +36,7 @@ public OAuthTokenInfo requestAccessToken(String authCode) {
Map<String, String> params = new LinkedHashMap<>();
params.put("grant_type", "authorization_code");
params.put("client_id", kakaoOAuthProperty.clientId());
params.put("redirect_uri", kakaoOAuthProperty.redirectUrl());
params.put("redirect_uri", kakaoOAuthProperty.redirectUri());
params.put("code", authCode);
params.put("client_secret", kakaoOAuthProperty.clientSecret());
KakaoTokenResponse kakaoTokenResponse = kakaoRequestApi.requestToken(params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
@ConfigurationProperties(prefix = "oauth.kakao")
public record KakaoOAuthProperty(
String clientId,
String redirectUrl,
String redirectUri,
String responseType,
String signInAuthorizeUrl,
String[] scope,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public class NaverOAuthClient implements OAuthClient {
private final NaverRequestApi naverRequestApi;

@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return UriComponentsBuilder
.fromUriString(naverOAuthProperty.signInAuthorizeUrl())
.queryParam("response_type", naverOAuthProperty.responseType())
.queryParam("client_id", naverOAuthProperty.clientId())
.queryParam("redirect_uri", naverOAuthProperty.redirectUri())
.queryParam("redirect_uri", host + naverOAuthProperty.redirectUri())
.queryParam("state", naverOAuthProperty.state())
.toUriString();
}
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/baro/auth/presentation/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.baro.auth.domain.AuthMember;
import com.baro.auth.domain.Token;
import com.baro.auth.presentation.dto.OAuthServiceUrlResponse;
import com.baro.common.presentation.RequestHost;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -24,8 +25,8 @@ public class AuthController {
private final OAuthInfoProvider oAuthInfoProvider;

@GetMapping("/oauth/{oauthType}")
ResponseEntity<OAuthServiceUrlResponse> signInRequestUrl(@PathVariable String oauthType) {
String signInUrl = oAuthInfoProvider.getSignInUrl(oauthType);
ResponseEntity<OAuthServiceUrlResponse> signInRequestUrl(@PathVariable String oauthType, @RequestHost String host) {
String signInUrl = oAuthInfoProvider.getSignInUrl(oauthType, host);
return ResponseEntity.ok(new OAuthServiceUrlResponse(signInUrl));
}

Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/baro/common/config/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.baro.auth.presentation.AuthInterceptor;
import com.baro.auth.presentation.AuthenticationArgumentResolver;
import com.baro.common.presentation.RequestHostArgumentResolver;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
Expand All @@ -15,10 +16,12 @@ public class WebConfig implements WebMvcConfigurer {

private final AuthenticationArgumentResolver authenticationArgumentResolver;
private final AuthInterceptor authInterceptor;
private final RequestHostArgumentResolver requestHostArgumentResolver;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(authenticationArgumentResolver);
resolvers.add(requestHostArgumentResolver);
}

@Override
Expand All @@ -27,6 +30,7 @@ public void addInterceptors(InterceptorRegistry registry) {
.addPathPatterns("/**")
.excludePathPatterns("/docs/**")
.excludePathPatterns("/auth/**")
.excludePathPatterns("/favicon.ico");
.excludePathPatterns("/favicon.ico")
.excludePathPatterns("/test/**");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public enum CommonRequestExceptionType implements RequestExceptionType {

MISSING_PARAMETER_EXCEPTION("CM01", "Request parameter is empty", HttpStatus.BAD_REQUEST),
INVALID_TYPE_REQUEST_EXCEPTION("CM02", "Request type is invalid", HttpStatus.BAD_REQUEST),
REQUIRED_HEADER_EXCEPTION("CM03", "Request header is empty", HttpStatus.BAD_REQUEST),
;

private final String errorCode;
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/baro/common/presentation/RequestHost.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.baro.common.presentation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(value = RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface RequestHost {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.baro.common.presentation;

import static com.baro.common.exception.CommonRequestExceptionType.REQUIRED_HEADER_EXCEPTION;

import com.baro.common.exception.RequestException;
import com.baro.common.exception.RequestExceptionType;
import java.util.Objects;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

@Component
public class RequestHostArgumentResolver implements HandlerMethodArgumentResolver {

private static final String HOST_HEADER_KEY = "Origin";

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestHost.class);
}

@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
String host = webRequest.getHeader(HOST_HEADER_KEY);
validateHeaderIsNonNull(host);
return host;
}

private void validateHeaderIsNonNull(String host) {
if (Objects.nonNull(host)) {
return;
}

throw new RequestException() {
@Override
public RequestExceptionType exceptionType() {
return REQUIRED_HEADER_EXCEPTION;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,36 +33,39 @@ void setUp() {
void 카카오의_SignInUrl을_가져온다() {
// given
String oAuthService = OAuthServiceType.KAKAO.name();
String host = "http://localhost:3000";

// when
String signInUrl = oAuthInfoProvider.getSignInUrl(oAuthService);
String signInUrl = oAuthInfoProvider.getSignInUrl(oAuthService, host);

// then
assertThat(signInUrl).isEqualTo(fakeKakaoOAuthClient.getSignInUrl());
assertThat(signInUrl).isEqualTo(fakeKakaoOAuthClient.getSignInUrl(host));
}

@Test
void 네이버의_SignInUrl을_가져온다() {
// given
String oAuthService = OAuthServiceType.NAVER.name();
String host = "http://localhost:3000";

// when
String signInUrl = oAuthInfoProvider.getSignInUrl(oAuthService);
String signInUrl = oAuthInfoProvider.getSignInUrl(oAuthService, host);

// then
assertThat(signInUrl).isEqualTo(fakeNaverOAuthClient.getSignInUrl());
assertThat(signInUrl).isEqualTo(fakeNaverOAuthClient.getSignInUrl(host));
}

@Test
void 구글의_SignInUrl을_가져온다() {
// given
String oAuthService = OAuthServiceType.GOOGLE.name();
String host = "http://localhost:3000";

// when
String signInUrl = oAuthInfoProvider.getSignInUrl(oAuthService);
String signInUrl = oAuthInfoProvider.getSignInUrl(oAuthService, host);

// then
assertThat(signInUrl).isEqualTo(fakeGoogleOAuthClient.getSignInUrl());
assertThat(signInUrl).isEqualTo(fakeGoogleOAuthClient.getSignInUrl(host));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class FakeGoogleOAuthClient implements OAuthClient {

@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class FakeKakaoOAuthClient implements OAuthClient {

@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public class FakeNaverOAuthClient implements OAuthClient {
@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ class OAuthApiTest extends RestApiTest {

@Test
void OAuth_로그인시_필요한_url을_반환한다() {
// givne
var 요청_호스트 = "http://localhost:3000";

// when
var 응답 = 리다이렉트_URI_요청("kakao");
var 응답 = 리다이렉트_URI_요청("kakao", 요청_호스트);

// then
응답값을_검증한다(응답, 성공);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

public class OAuthAcceptanceSteps {

public static ExtractableResponse<Response> 리다이렉트_URI_요청(String oauthServiceType) {
public static ExtractableResponse<Response> 리다이렉트_URI_요청(String oauthServiceType, String 요청_호스트) {
var url = "/auth/oauth/{oauthType}";

return given(requestSpec).log().all()
Expand All @@ -29,6 +29,7 @@ public class OAuthAcceptanceSteps {
)
))
.contentType(MediaType.APPLICATION_JSON_VALUE)
.header("Origin", 요청_호스트)
.when().get(url, oauthServiceType)
.then().log().all()
.extract();
Expand Down
Loading

0 comments on commit 85919c9

Please sign in to comment.