Skip to content

Commit

Permalink
fix: 구글로그인 idToken 사용하도록 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
daeunkwak committed Sep 17, 2023
1 parent 62a9d39 commit 1e1b6bb
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 9 deletions.
21 changes: 16 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,27 @@ dependencies {
// image metadata
implementation 'com.drewnoakes:metadata-extractor:2.9.1'

// gson
// implementation 'com.google.code.gson:gson:2.8.8'
implementation 'com.google.api-client:google-api-client-gson:1.35.1'

// json
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.4'

// gdrive
// implementation 'com.google.api-client:google-api-client:1.30.9'
//implementation 'com.google.api-client:google-api-client:1.30.9'
//implementation 'com.google.oauth-client:google-oauth-client-jetty:RELEASE'

//
implementation 'com.google.api-client:google-api-client:1.31.1'
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.31.1'
implementation 'com.google.apis:google-api-services-drive:v2-rev20220815-2.0.0'
// implementation 'com.google.apis:google-api-services-drive:v2-rev20220815-2.0.0'
//
// implementation 'com.fasterxml.jackson.core:jackson-core:2.12.4'
// implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.4'
// implementation 'com.fasterxml.jackson.core:jackson-annotations:2.12.4'
///

implementation 'com.fasterxml.jackson.core:jackson-core:2.12.4'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.4'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.12.4'

// map
//implementation 'org.springframework.cloud:spring-cloud-starter-gcp'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class OauthLoginController {

@Tag(name = "oauth")
@PostMapping(value = "/login", headers = {"Content-type=application/json"}, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "OAuth 로그인 API", description = "Authorization code로 로그인 시 JWT 토큰 반환, 현재 GOOGLE만 지원")
@Operation(summary = "OAuth 로그인 API")
public ResponseEntity<ResponseJwtTokenDto> loginOauth(HttpServletRequest httpServletRequest) {
log.info("=== Oauth login start ===");

Expand All @@ -39,7 +39,7 @@ public ResponseEntity<ResponseJwtTokenDto> loginOauth(HttpServletRequest httpSer

final SocialType socialType = SocialType.GOOGLE;

final ResponseJwtTokenDto jwtTokenDto = oauthLoginService.login(socialType, httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION));
final ResponseJwtTokenDto jwtTokenDto = oauthLoginService.googleLoginV2(httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION));

log.info("=== Oauth login end ===");
return ResponseEntity.ok(jwtTokenDto);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package app.gangdan.please.service.google;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
//import com.google.api.services.drive.Drive;
//import com.google.api.services.drive.model.File;
import com.google.api.client.http.FileContent;
import org.springframework.web.multipart.MultipartFile;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,29 @@
import app.gangdan.please.dto.member.jwt.TokenDto;
import app.gangdan.please.dto.oauth.OAuthAttributes;
import app.gangdan.please.dto.oauth.OauthLoginDto;
import app.gangdan.please.global.exception.BadRequestException;
import app.gangdan.please.global.exception.MemberTokenNotFoundException;
import app.gangdan.please.service.jwt.TokenProvider;
import app.gangdan.please.service.oauth.google.GoogleFeignService;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.apache.v2.ApacheHttpTransport;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.json.*;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidParameterException;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Optional;

@Slf4j
Expand All @@ -36,6 +46,92 @@ public class OauthLoginService {
private final MemberRepository memberRepository;
private final MemberTokenRepository memberTokenRepository;

@Value("${oauth2.clientId}")
private String CLIENT_ID;

public ResponseJwtTokenDto googleLoginV2(String tokenString) {

Member requestMember;
GoogleIdToken idToken = getVerifiedIdToken(tokenString);

if (idToken == null) {
throw new BadRequestException("Invalid token");
}

GoogleIdToken.Payload payload = idToken.getPayload();

// Get profile information from payload
String email = payload.getEmail();

OAuthAttributes socialUserInfo = generateSocialInfoFromIdToken(idToken);

log.info("oauthAttributes: {}", socialUserInfo.toString());

final Optional<Member> foundMember = memberRepository.findByEmail(email);

if (foundMember.isEmpty()) { // 기존 회원 아닐 때
Member newMember = Member.create(socialUserInfo);
requestMember = memberRepository.save(newMember);
} else {
requestMember = foundMember.get(); // 기존 회원일 때
}

// JWT 토큰 생성
ResponseJwtTokenDto responseJwtTokenDto = generateToken(requestMember);

return responseJwtTokenDto;
}

public GoogleIdToken getVerifiedIdToken(String idTokenString) {
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier
.Builder(
new ApacheHttpTransport(ApacheHttpTransport.newDefaultHttpClient()),
new GsonFactory()
)
.setAudience(Collections.singletonList(CLIENT_ID))
.setIssuer("https://accounts.google.com")
.build();
try {
return verifier.verify(idTokenString);
} catch (GeneralSecurityException | IOException e) {
return null;
}
}

public OAuthAttributes generateSocialInfoFromIdToken(GoogleIdToken idToken) {
GoogleIdToken.Payload payload = idToken.getPayload();

// Print user identifier
String userId = payload.getSubject();

// Get profile information from payload
String email = payload.getEmail();
String name = (String) payload.get("name");

return OAuthAttributes
.builder()
.email(StringUtils.isBlank(email) ? userId : email) // 이메일 동의 x 경우
.name(name)
.socialType(SocialType.GOOGLE)
.build();
}

public ResponseJwtTokenDto generateToken(Member member) {
// JWT 토큰 생성
TokenDto tokenDto = tokenProvider.createTokenDto(member.getMemberId());
log.info("tokenDto: {}", tokenDto);

ResponseJwtTokenDto responseJwtTokenDto = modelMapper.map(tokenDto, ResponseJwtTokenDto.class);
final boolean isNewMember = StringUtils.isEmpty(member.getUsername());
responseJwtTokenDto.setIsNewMember(isNewMember);
if (!isNewMember) {
responseJwtTokenDto.setMemberName(member.getUsername());
}
responseJwtTokenDto.setMemberId(member.getMemberId());

return responseJwtTokenDto;
}


// 7
public ResponseJwtTokenDto createMemberAndJwt(OauthLoginDto oauthLoginDto) {
Expand Down

0 comments on commit 1e1b6bb

Please sign in to comment.