Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify Google OAuth logic #89

Merged
merged 5 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public ResponseEntity<Message> naverCallback(@RequestParam String code, @Request
}

@PostMapping("/sign-in/kakao")
@Operation(summary = "카카오 로그인 콜백 메서드", description = "카카오 로그인 콜백을 하기 위한 메서드입니다.")
@Operation(summary = "카카오 로그인 메서드", description = "카카오 로그인을 하기 위한 메서드입니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "카카오 로그인 성공"),
@ApiResponse(responseCode = "400(400-1)", description = "잘못된 프로토콜 요청"),
Expand All @@ -185,22 +185,15 @@ public ResponseEntity<Message> kakaoCallback(@RequestBody TokenDto dto) throws I
);
}

@GetMapping("/sign-in/google")
@Operation(summary = "구글 로그인 메서드", description = "구글 로그인 후 리다이렉트 되어 인가 코드를 출력하는 메서드입니다.")
public void googleLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect(googleService.getAuthorizationUrl());
}

@GetMapping("/sign-in/google/callback")
@Operation(summary = "구글 로그인 콜백 메서드", description = "구글로부터 사용자 정보를 얻어와 회원가입 및 로그인을 하기 위한 메서드입니다.")
@PostMapping("/sign-in/google")
@Operation(summary = "구글 로그인 메서드", description = "구글로부터 사용자 정보를 얻어와 회원가입 및 로그인을 하기 위한 메서드입니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "구글 로그인 성공"),
@ApiResponse(responseCode = "400(400)", description = "잘못된 프로토콜 혹은 URL 요쳥"),
@ApiResponse(responseCode = "400(500)", description = "HTTP 연결 수행 실패"),
})
public ResponseEntity<Message> signIn(@RequestParam String code) throws IOException {
TokenDto googleTokenDto = googleService.getToken(code);
GoogleDto googleDto = googleService.getUserInfo(googleTokenDto);
public ResponseEntity<Message> signIn(@RequestBody TokenDto dto) throws IOException {
GoogleDto googleDto = googleService.getUserInfo(dto);
TokenDto tokenDto = googleService.signIn(googleDto);
Member member = memberService.read(googleDto.getUsername());
oAuthService.save(member, OAuthPlatform.GOOGLE, googleDto.getId());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package org.swmaestro.repl.gifthub.auth.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
Expand All @@ -13,7 +11,6 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
import org.swmaestro.repl.gifthub.auth.dto.GoogleDto;
import org.swmaestro.repl.gifthub.auth.dto.TokenDto;
import org.swmaestro.repl.gifthub.auth.entity.Member;
Expand All @@ -25,106 +22,20 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import lombok.RequiredArgsConstructor;

@Service
@PropertySource("classpath:application.yml")
@RequiredArgsConstructor
public class GoogleService {
private final MemberService memberService;
private final MemberRepository memberRepository;
private final RefreshTokenService refreshTokenService;
private final JwtProvider jwtProvider;
private final String clientId;
private final String redirectUri;
private final String clientSecret;

private final String tokenUri;

private final String userInfoUri;
private final String authorizationUri;

public GoogleService(MemberService memberService, MemberRepository memberRepository, RefreshTokenService refreshTokenService, JwtProvider jwtProvider,
@Value("${google.client_id}") String clientId, @Value("${google.client_secret}") String clientSecret,
@Value("${google.redirect_uri}") String redirectUri,
@Value("${google.token_uri}") String tokenUri, @Value("${google.user_info_uri}") String userInfoUri,
@Value("${google.authorization_uri}") String authorizationUri) {
this.memberService = memberService;
this.memberRepository = memberRepository;
this.refreshTokenService = refreshTokenService;
this.jwtProvider = jwtProvider;
this.clientId = clientId;
this.redirectUri = redirectUri;
this.clientSecret = clientSecret;
this.tokenUri = tokenUri;
this.userInfoUri = userInfoUri;
this.authorizationUri = authorizationUri;
}

public String getAuthorizationUrl() {
return UriComponentsBuilder
.fromUriString(authorizationUri)
.queryParam("client_id", clientId)
.queryParam("redirect_uri", redirectUri)
.queryParam("response_type", "code")
.queryParam("scope", "email profile")
.build()
.toString();
}

public TokenDto getToken(String code) {

TokenDto tokenDto = null;

try {
URL url = new URL(tokenUri);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();

conn.setRequestMethod("POST");
conn.setDoOutput(true);

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
StringBuilder sb = new StringBuilder();

sb.append("grant_type=authorization_code");
sb.append("&client_id=" + clientId);
sb.append("&client_secret=" + clientSecret);
sb.append("&redirect_uri=" + redirectUri);
sb.append("&code=" + code);

bw.write(sb.toString());
bw.flush();

int responseCode = conn.getResponseCode();

BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

String line = "";
String result = "";

while ((line = br.readLine()) != null) {
result += line;
}

JsonParser parser = new JsonParser();
JsonElement element = parser.parse(result);

String accessToken = element.getAsJsonObject().get("access_token").getAsString();

br.close();
bw.close();
tokenDto = TokenDto.builder()
.accessToken(accessToken)
.build();
} catch (ProtocolException e) {
throw new BusinessException("잘못된 프로토콜을 사용하였습니다.", StatusEnum.BAD_REQUEST);
} catch (MalformedURLException e) {
throw new BusinessException("잘못된 URL 형식을 사용하였습니다.", StatusEnum.BAD_REQUEST);
} catch (IOException e) {
throw new BusinessException("HTTP 연결을 수행하는 동안 입출력 관련 오류가 발생하였습니다.", StatusEnum.INTERNAL_SERVER_ERROR);
}
return tokenDto;
}
@Value("${google.user_info_uri}")
private String userInfoUri;

public GoogleDto getUserInfo(TokenDto tokenDto) {

GoogleDto googleDto = null;

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,34 +169,24 @@ public void kakaoSignInTest() throws Exception {
}

@Test
public void googleSignInCallbackTest() throws Exception {
String accesstoken = "myawesome_accesstoken";
String code = "myawesome_code";
String state = "myawesome_state";
public void googleSignInTest() throws Exception {

TokenDto googleTokenDto = TokenDto.builder()
.accessToken("myawesomeKakaojwt")
.refreshToken("myawesomeKakaojwt")
.build();

TokenDto tokenDto = TokenDto.builder()
.accessToken("myawesomejwt")
.refreshToken("myawesomejwt")
.accessToken("my.awesome.google.jwt")
.refreshToken("my.awesome.google.jwt")
.build();

GoogleDto googleDto = GoogleDto.builder()
.nickname("정인희")
.username("[email protected]")
.build();

when(googleService.getToken(code)).thenReturn(tokenDto);
when(googleService.getUserInfo(tokenDto)).thenReturn(googleDto);
when(googleService.signIn(googleDto)).thenReturn(tokenDto);
when(googleService.getUserInfo(googleTokenDto)).thenReturn(googleDto);
when(googleService.signIn(googleDto)).thenReturn(googleTokenDto);

mockMvc.perform(get("/auth/sign-in/google/callback")
.queryParam("code", code)
.queryParam("state", state)
.header("Authorization", "Bearer " + accesstoken))
mockMvc.perform(post("/auth/sign-in/google")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(googleTokenDto)))
.andExpect(status().isOk());
}

Expand Down