Skip to content

Commit

Permalink
Merge pull request #69 from Developer-Wikis/feature/#62
Browse files Browse the repository at this point in the history
Feat : code와 url 받아서 사용자 정보 조회
  • Loading branch information
jhdl0157 authored Oct 26, 2022
2 parents 92eec97 + 994d5d6 commit d9f3621
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 2 deletions.
23 changes: 23 additions & 0 deletions src/main/java/com/developer/wiki/config/RestTemplateConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.developer.wiki.config;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;

@Configuration
public class RestTemplateConfig {
//HTTP get,post 요청을 날릴때 일정한 형식에 맞춰주는 template
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder
.requestFactory(() -> new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()))
.additionalMessageConverters(new StringHttpMessageConverter(Charset.forName("UTF-8")))
.build();
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/developer/wiki/oauth/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import javax.persistence.*;

@Entity
@DynamicUpdate
@Table(name = "user")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -30,7 +29,7 @@ public class User {
@Enumerated(value = EnumType.STRING)
private Role role;

User(String name, String email){
public User(String name, String email){
if(name.isEmpty() || email.isEmpty()){
throw new BadRequestException("email or name 값이 없습니다.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.developer.wiki.oauth.controller;

import com.developer.wiki.oauth.dto.GoogleResponseDto;
import com.developer.wiki.oauth.dto.UrlRequest;
import com.developer.wiki.oauth.service.OauthService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/oauth")
public class OauthController {
private final OauthService oauthService;
@PostMapping("")
public ResponseEntity<GoogleResponseDto> getGoogleUserInfo(@RequestBody @Valid UrlRequest urlRequest) throws IOException {
System.out.println(">> 소셜 로그인 API 서버로부터 받은 code :"+ urlRequest.getCode());
System.out.println(">> 소셜 로그인 API 서버로부터 받은 url :"+ urlRequest.getRedirectUrl());
GoogleResponseDto GoogleUser = oauthService.oAuthLogin(urlRequest.getCode(),urlRequest.getRedirectUrl());
return new ResponseEntity<>(GoogleUser, HttpStatus.OK);
}
@GetMapping("/google/url")
public void getGoogleUrl(@RequestParam String url, HttpServletResponse response) throws IOException {
System.out.println("asdasdasd"+url);
String redirectUrl=oauthService.googleUrl(url);
response.sendRedirect(redirectUrl);
}
}
16 changes: 16 additions & 0 deletions src/main/java/com/developer/wiki/oauth/dto/GoogleOAuthToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.developer.wiki.oauth.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@AllArgsConstructor
@Getter
@Setter
public class GoogleOAuthToken {
private String access_token;
private int expires_in;
private String scope;
private String token_type;
private String id_token;
}
21 changes: 21 additions & 0 deletions src/main/java/com/developer/wiki/oauth/dto/GoogleResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.developer.wiki.oauth.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class GoogleResponseDto {
String userName;
String userEmail;
String jwtToken;
String RefreshToken;
String tokenType;
public GoogleResponseDto(String userName,String userEmail, String jwtToken,String RefreshToken){
this.userName=userName;
this.userEmail=userEmail;
this.jwtToken=jwtToken;
this.RefreshToken=RefreshToken;
this.tokenType="Auth";
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/developer/wiki/oauth/dto/GoogleUser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.developer.wiki.oauth.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@AllArgsConstructor
@Getter
@Setter
public class GoogleUser {
public String id;
public String email;
public Boolean verifiedEmail;
public String name;
public String givenName;
public String familyName;
public String picture;
public String locale;
}
14 changes: 14 additions & 0 deletions src/main/java/com/developer/wiki/oauth/dto/UrlRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.developer.wiki.oauth.dto;

import lombok.Getter;

import javax.validation.constraints.NotBlank;

@Getter
public class UrlRequest {
@NotBlank(message = "Code값이 없습니다.")
String code;

@NotBlank(message = "redirectUrl값이 없습니다.")
String redirectUrl;
}
107 changes: 107 additions & 0 deletions src/main/java/com/developer/wiki/oauth/service/GoogleOauthService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.developer.wiki.oauth.service;

import com.developer.wiki.common.exception.BadRequestException;
import com.developer.wiki.oauth.dto.GoogleOAuthToken;
import com.developer.wiki.oauth.dto.GoogleUser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class GoogleOauthService {
private final RestTemplate restTemplate;

private final ObjectMapper objectMapper;
@Value("${custom.google.client-id}")
private String GOOGLE_SNS_CLIENT_ID;

@Value("${custom.google.client-secret}")
private String GOOGLE_SNS_CLIENT_SECRET;

@Value("${custom.google.scope}")
private String GOOGLE_SCOPE;
private String REDIRECT_URL;


public String googleInitUrl(String url) {
StringBuilder stringBuilder=new StringBuilder();
REDIRECT_URL=url;
Map<String, Object> params = new HashMap<>();
params.put("client_id", GOOGLE_SNS_CLIENT_ID);
params.put("redirect_uri", url);
params.put("response_type", "code");
params.put("scope", GOOGLE_SCOPE);

String paramStr = params.entrySet().stream()
.map(param -> param.getKey() + "=" + param.getValue())
.collect(Collectors.joining("&"));
return stringBuilder
.append("https://accounts.google.com/")
.append("o/oauth2/v2/auth?")
.append(paramStr)
.toString();
}

public ResponseEntity<String> requestAccessToken(String code,String redirectUrl) {
String GOOGLE_TOKEN_REQUEST_URL="https://oauth2.googleapis.com/token";
RestTemplate restTemplate=new RestTemplate();
Map<String, Object> params = new HashMap<>();
params.put("code", code);
params.put("client_id", GOOGLE_SNS_CLIENT_ID);
params.put("client_secret", GOOGLE_SNS_CLIENT_SECRET);
params.put("redirect_uri", redirectUrl);
params.put("grant_type", "authorization_code");
try {
ResponseEntity<String> responseEntity=restTemplate.postForEntity(GOOGLE_TOKEN_REQUEST_URL,
params,String.class);
return responseEntity;
}catch (RestClientException e){
e.printStackTrace();
throw new BadRequestException(String.format("인가코드로 구글의 AccessToken을 발급하지 못했습니다. code : %s, redirectUrl : %s",code,redirectUrl));
}
}

public GoogleOAuthToken getAccessToken(ResponseEntity<String> response) throws JsonProcessingException {
System.out.println("response.getBody() = " + response.getBody());
GoogleOAuthToken googleOAuthToken= objectMapper.readValue(response.getBody(),GoogleOAuthToken.class);
return googleOAuthToken;

}

public ResponseEntity<String> requestUserInfo(GoogleOAuthToken oAuthToken) {
String GOOGLE_USERINFO_REQUEST_URL="https://www.googleapis.com/oauth2/v1/userinfo";

//header에 accessToken을 담는다.
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization","Bearer "+oAuthToken.getAccess_token());

//HttpEntity를 하나 생성해 헤더를 담아서 restTemplate으로 구글과 통신하게 된다.
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity(headers);
try {
ResponseEntity<String> response=restTemplate.exchange(GOOGLE_USERINFO_REQUEST_URL, HttpMethod.GET,request,String.class);
System.out.println("response.getBody() = " + response.getBody());
return response;
}catch (RestClientException e){
throw new BadRequestException("구글 AccessToken을 으로 사용자 정보를 가져오지 못했습니다.");
}
}

public GoogleUser getUserInfo(ResponseEntity<String> userInfoRes) throws JsonProcessingException{
GoogleUser googleUser=objectMapper.readValue(userInfoRes.getBody(),GoogleUser.class);
return googleUser;
}
}
39 changes: 39 additions & 0 deletions src/main/java/com/developer/wiki/oauth/service/OauthService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.developer.wiki.oauth.service;

import com.developer.wiki.oauth.*;
import com.developer.wiki.oauth.dto.GoogleOAuthToken;
import com.developer.wiki.oauth.dto.GoogleResponseDto;
import com.developer.wiki.oauth.dto.GoogleUser;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
@RequiredArgsConstructor
public class OauthService {
private final GoogleOauthService googleOauthService;
private final TokenService tokenService;
private final UserRepository userRepository;
public GoogleResponseDto oAuthLogin(String code, String redirectUrl) throws IOException {
ResponseEntity<String> accessTokenResponse= googleOauthService.requestAccessToken(code,redirectUrl);
GoogleOAuthToken oAuthToken=googleOauthService.getAccessToken(accessTokenResponse);
ResponseEntity<String> userInfoResponse=googleOauthService.requestUserInfo(oAuthToken);
GoogleUser googleUser= googleOauthService.getUserInfo(userInfoResponse);
User user =userRepository.findByEmail(googleUser.getEmail()).orElse(null);
if(user==null) {
User user1 = new User(
googleUser.getName(),
googleUser.getEmail());
userRepository.save(user1);
}
Token token = tokenService.generateToken(googleUser.getEmail(), "ROLE_USER");
GoogleResponseDto googleResponseDto=new GoogleResponseDto(googleUser.getName(),googleUser.getEmail(),token.getJwtToken(),token.getRefreshToken());
return googleResponseDto;
}

public String googleUrl(String url){
return googleOauthService.googleInitUrl(url);
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
spring:
main:
allow-bean-definition-overriding: true
config:
import: application-oauth.yaml
jpa:
open-in-view: false
show-sql: true
Expand Down

0 comments on commit d9f3621

Please sign in to comment.