Skip to content

Commit

Permalink
Merge pull request #27 from Bamdoliro/perf/#26
Browse files Browse the repository at this point in the history
[개선] 구글 로그인 코드 리팩토링
  • Loading branch information
cabbage16 authored Nov 24, 2024
2 parents bd92e27 + 233f7ac commit c10d941
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 122 deletions.
29 changes: 12 additions & 17 deletions src/docs/asciidoc/auth.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
== 인증 Auth

=== Google 계정으로 로그인/회원가입 링크 발급
구글 로그인/회원가입 링크를 발급받을 수 있습니다.
Google 계정으로 로그인 링크를 발급받을 수 있습니다.

==== 요청 형식

Expand All @@ -13,42 +13,37 @@ include::{snippets}/auth-controller-test/구글_로그인_링크를_발급받는
===== 정상 응답
include::{snippets}/auth-controller-test/구글_로그인_링크를_발급받는다/http-response.adoc[]

=== Google Access Token 발급
Google Authorization Code를 통해서 Access Token을 발급받을 수 있습니다.
=== 웹에서 Google 계정으로 로그인
웹에서 Google 계정을 통해서 로그인/회원가입을 할 수 있습니다

==== 요청 형식

===== Query Parameter
include::{snippets}/auth-controller-test/유저가_웹에서_구글_액세스_토큰을_발급받는다/query-parameters.adoc[]
include::{snippets}/auth-controller-test/유저가_웹에서_구글로_로그인한다/query-parameters.adoc[]

==== 요청
include::{snippets}/auth-controller-test/유저가_웹에서_구글_액세스_토큰을_발급받는다/http-request.adoc[]
include::{snippets}/auth-controller-test/유저가_웹에서_구글로_로그인한다/http-request.adoc[]

==== 응답
===== 응답

===== 정상 응답
include::{snippets}/auth-controller-test/유저가_웹에서_구글_액세스_토큰을_발급받는다/response-body.adoc[]
include::{snippets}/auth-controller-test/유저가_웹에서_구글로_로그인한다/http-response.adoc[]

=== Google 계정으로 로그인
Google 계정을 통해서 로그인/회원가입을 할 수 있습니다
=== 앱에서 Google 계정으로 로그인
앱에서 Google 계정을 통해서 로그인/회원가입을 할 수 있습니다

==== 요청 형식

===== Request Fields
include::{snippets}/auth-controller-test/유저가_웹에서_구글로_로그인한다/request-fields.adoc[]
include::{snippets}/auth-controller-test/유저가_앱에서_구글로_로그인한다/request-fields.adoc[]

==== 요청

===== 웹에서 로그인 하는 경우
include::{snippets}/auth-controller-test/유저가_웹에서_구글로_로그인한다/http-request.adoc[]

===== 앱에서 로그인 하는 경우
include::{snippets}/auth-controller-test/유저가_앱에서_구글로_로그인한다/http-request.adoc[]

===== 응답
==== 응답

===== 정상 응답
include::{snippets}/auth-controller-test/유저가_웹에서_구글로_로그인한다/http-response.adoc[]
include::{snippets}/auth-controller-test/유저가_앱에서_구글로_로그인한다/http-response.adoc[]

=== 액세스 토큰 재발급
리프레시 토큰을 입력해 액세스 토큰을 재발급할 수 있습니다.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class GoogleAuthLinkUseCase {
"scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile";

public String execute() {
return googleOAuthProperties.getWeb().getBaseUrl()
+ String.format(QUERY_STRING, googleOAuthProperties.getWeb().getClientId(), googleOAuthProperties.getWeb().getRedirectUri());
return googleOAuthProperties.getGoogle().getBaseUrl()
+ String.format(QUERY_STRING, googleOAuthProperties.getGoogle().getClientId(), googleOAuthProperties.getGoogle().getRedirectUri());
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.bamdoliro.sinabro.application.auth;

import com.bamdoliro.sinabro.domain.auth.service.GoogleAuthService;
import com.bamdoliro.sinabro.infrastructure.oauth.google.feign.GoogleAuthClient;
import com.bamdoliro.sinabro.infrastructure.oauth.google.feign.GoogleInformationWebClient;
import com.bamdoliro.sinabro.infrastructure.oauth.google.feign.dto.request.GoogleAuthRequest;
import com.bamdoliro.sinabro.infrastructure.oauth.google.feign.dto.response.GoogleInformation;
import com.bamdoliro.sinabro.presentation.auth.dto.request.GoogleTokenRequest;
import com.bamdoliro.sinabro.presentation.auth.dto.response.TokenResponse;
import com.bamdoliro.sinabro.shared.annotation.UseCase;
import com.bamdoliro.sinabro.shared.config.properties.GoogleOAuthProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -15,11 +17,25 @@ public class GoogleAuthWebUseCase {

private final GoogleInformationWebClient googleInformationWebClient;
private final GoogleAuthService googleAuthService;
private final GoogleAuthClient googleAuthClient;
private final GoogleOAuthProperties googleOAuthProperties;

@Transactional
public TokenResponse execute(GoogleTokenRequest request) {
GoogleInformation information = googleInformationWebClient.getUserInformation("Bearer " + request.getToken());
public TokenResponse execute(String code) {
String accessToken = googleAuthClient
.getAccessToken(createGoogleAuthRequest(code))
.getAccessToken();
GoogleInformation information = googleInformationWebClient.getUserInformation("Bearer " + accessToken);

return googleAuthService.execute(information);
}

private GoogleAuthRequest createGoogleAuthRequest(String code) {
return GoogleAuthRequest.builder()
.code(code)
.clientId(googleOAuthProperties.getGoogle().getClientId())
.redirectUri(googleOAuthProperties.getGoogle().getRedirectUri())
.clientSecret(googleOAuthProperties.getGoogle().getClientSecret())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
public class AuthController {

private final GoogleAuthLinkUseCase googleAuthLinkUseCase;
private final GetGoogleAccessTokenUseCase getGoogleAccessTokenUseCase;
private final RefreshAccessTokenUseCase refreshAccessTokenUseCase;
private final LogOutUseCase logOutUseCase;
private final GoogleAuthWebUseCase googleAuthWebUseCase;
Expand All @@ -32,17 +31,10 @@ public SingleCommonResponse<String> getGoogleAuthUrl() {
);
}

@GetMapping("/google")
public SingleCommonResponse<String> getGoogleAccessToken(@RequestParam String code) {
return CommonResponse.ok(
getGoogleAccessTokenUseCase.execute(code)
);
}

@PostMapping("/google/web")
public SingleCommonResponse<TokenResponse> authWithGoogleWeb(@RequestBody @Valid GoogleTokenRequest request) {
public SingleCommonResponse<TokenResponse> authWithGoogleWeb(@RequestParam String code) {
return CommonResponse.ok(
googleAuthWebUseCase.execute(request)
googleAuthWebUseCase.execute(code)
);
}

Expand All @@ -62,9 +54,7 @@ public SingleCommonResponse<TokenResponse> refreshAccessToken(@RequestHeader(Htt

@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping
public void logOut(
@AuthenticationPrincipal User user
) {
public void logOut(@AuthenticationPrincipal User user) {
logOutUseCase.execute(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@
@Getter
@Setter
@Configuration
@ConfigurationProperties("auth.google")
@ConfigurationProperties("auth")
public class GoogleOAuthProperties {

private OAuth web;
private OAuth android;
private OAuth ios;
private OAuth google;

@Getter
@Setter
Expand Down
13 changes: 4 additions & 9 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,10 @@ spring:

auth:
google:
web:
base-url: ${GOOGLE_WEB_BASE_URL}
client-id: ${GOOGLE_WEB_CLIENT_ID}
client-secret: ${GOOGLE_WEB_CLIENT_SECRET}
redirect-uri: ${GOOGLE_WEB_REDIRECT_URI}
android:
client-id: ${GOOGLE_ANDROID_CLIENT_ID}
ios:
client-id: ${GOOGLE_IOS_CLIENT_ID}
base-url: ${GOOGLE_BASE_URL}
client-id: ${GOOGLE_CLIENT_ID}
client-secret: ${GOOGLE_CLIENT_SECRET}
redirect-uri: ${GOOGLE_REDIRECT_URI}

jwt:
refresh-expiration-time: 1296000000 # 15일
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,50 +41,27 @@ class AuthControllerTest extends RestDocsTestSupport {
verify(googleAuthLinkUseCase, times(1)).execute();
}

@Test
void 유저가_웹에서_구글_액세스_토큰을_발급받는다() throws Exception {
given(getGoogleAccessTokenUseCase.execute(any(String.class))).willReturn(AuthFixture.createGoogleToken());

mockMvc.perform(get("/auth/google")
.queryParam("code", AuthFixture.createGoogleOAuthCode())
.accept(MediaType.APPLICATION_JSON)
)

.andExpect(status().isOk())

.andDo(restDocs.document(
queryParameters(
parameterWithName("code")
.description("Google OAuth 인증 코드. 리다이렉트시 url에 포함됨")
)
));
verify(getGoogleAccessTokenUseCase, times(1)).execute(any(String.class));
}

@Test
void 유저가_웹에서_구글로_로그인한다() throws Exception {
GoogleTokenRequest request = new GoogleTokenRequest(AuthFixture.createGoogleToken());
TokenResponse response = new TokenResponse(AuthFixture.createAccessTokenString(), AuthFixture.createRefreshTokenString());

given(googleAuthWebUseCase.execute(any(GoogleTokenRequest.class))).willReturn(response);
given(googleAuthWebUseCase.execute(any(String.class))).willReturn(response);

mockMvc.perform(post("/auth/google/web")
.queryParam("code", AuthFixture.createGoogleOAuthCode())
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(toJson(request))
)

.andExpect(status().isOk())

.andDo(restDocs.document(
requestFields(
fieldWithPath("token")
.type(JsonFieldType.STRING)
.description("구글에서 발급받은 액세스 토큰 혹은 아이디 토큰")
queryParameters(
parameterWithName("code")
.description("Google OAuth 인증 코드. 리다이렉트시 url에 포함됨")
)
));

verify(googleAuthWebUseCase, times(1)).execute(any(GoogleTokenRequest.class));
verify(googleAuthWebUseCase, times(1)).execute(any(String.class));
}

@Test
Expand All @@ -106,7 +83,7 @@ class AuthControllerTest extends RestDocsTestSupport {
requestFields(
fieldWithPath("token")
.type(JsonFieldType.STRING)
.description("구글에서 발급받은 액세스 토큰 혹은 아이디 토큰")
.description("구글에서 발급받은 아이디 토큰")
)
));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
package com.bamdoliro.sinabro.shared.util;

import com.bamdoliro.sinabro.application.auth.GoogleAuthLinkUseCase;
import com.bamdoliro.sinabro.application.auth.LogOutUseCase;
import com.bamdoliro.sinabro.application.auth.RefreshAccessTokenUseCase;
import com.bamdoliro.sinabro.application.auth.*;
import com.bamdoliro.sinabro.application.character.GetCharacterUseCase;
import com.bamdoliro.sinabro.application.diary.*;
import com.bamdoliro.sinabro.application.notification.SendNotificationToAllUserUseCase;
import com.bamdoliro.sinabro.application.question.*;
import com.bamdoliro.sinabro.domain.auth.service.TokenService;
import com.bamdoliro.sinabro.presentation.auth.AuthController;
import com.bamdoliro.sinabro.presentation.diary.DiaryController;
import com.bamdoliro.sinabro.application.character.SelectCharacterUseCase;
import com.bamdoliro.sinabro.application.diary.*;
import com.bamdoliro.sinabro.application.fcm.token.DeleteFCMTokenUseCase;
import com.bamdoliro.sinabro.application.fcm.token.SaveFCMTokenUseCase;
import com.bamdoliro.sinabro.application.letter.GenerateLetterUseCase;
import com.bamdoliro.sinabro.application.letter.GetAllLetterUseCase;
import com.bamdoliro.sinabro.application.letter.GetLetterUseCase;
import com.bamdoliro.sinabro.application.notification.QueryNotificationListUseCase;
import com.bamdoliro.sinabro.application.notification.SendNotificationToAllUserUseCase;
import com.bamdoliro.sinabro.application.notification.SendNotificationUseCase;
import com.bamdoliro.sinabro.application.question.*;
import com.bamdoliro.sinabro.domain.auth.service.TokenService;
import com.bamdoliro.sinabro.presentation.auth.AuthController;
import com.bamdoliro.sinabro.presentation.character.CharacterController;
import com.bamdoliro.sinabro.presentation.diary.DiaryController;
import com.bamdoliro.sinabro.presentation.fcm.token.FCMTokenController;
import com.bamdoliro.sinabro.presentation.letter.LetterController;
import com.bamdoliro.sinabro.presentation.notification.NotificationController;
Expand Down Expand Up @@ -64,9 +61,6 @@ public abstract class ControllerTest {
@MockBean
protected GoogleAuthLinkUseCase googleAuthLinkUseCase;

@MockBean
protected GetGoogleAccessTokenUseCase getGoogleAccessTokenUseCase;

@MockBean
protected GoogleAuthWebUseCase googleAuthWebUseCase;

Expand Down

0 comments on commit c10d941

Please sign in to comment.