Google YouTube V3 API 사용하기, YouTube Api 사용하기2 (Spring Boot, YouTube V3 Api , Spring YouTube Library)

작성자 : 조회수 :

주의 : 해당 글은 공부 글이니 정확한 정보가 아닐 수도 있습니다. 주의해주세요.

1편에서 이어집니다.

 

1편 링크 : https://youseong.me/auth/skillboard/details/64



해당 리디렉션 URI를 통해서 진행합니다.


컨트롤 단에 먼저 클라이언트가 http:localhost:3030/youtube-check 라는 요청 시





@GetMapping(value = "/youtube-check")
public ResponseEntity youtubeCheck(){
   
String authUrl = "https://accounts.google.com/o/oauth2/v2/auth?" +
           
"scope=profile%20email%20openid%20https://www.googleapis.com/auth/youtube.readonly" +
           
"&client_id="+CLIENT_ID+
           
"&redirect_uri="+clientredirectyoutube+
           
"&response_type=code&mine=true";
   
URI redirectUri = null;

   
try {
        redirectUri =
new URI(authUrl);
       
HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.
setLocation(redirectUri);
       
log.info("check login");
       
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
    }
catch (URISyntaxException e) {
       
e.printStackTrace();
    }

   
return ResponseEntity.badRequest().build();
}

 

Client ID Client Redirection을 담아 youtube 인증 요청을 먼저 시도합니다.

 

 

@GetMapping(value = "/oauth/youtube/redirect")
public ResponseEntity<ChannelListResponse> redirectGoogleYoutube(
       
@RequestParam(value = "code") String authCode
) {
   
RestTemplate restTemplate = new RestTemplate();

   
GoogleLoginRequest requestParams = GoogleLoginRequest.builder()
            .
clientId(configUtils.getClientid())
            .
clientSecret(configUtils.getClientsecret())
            .
code(authCode)
            .
redirectUri(configUtils.getClientredirectyoutube())
            .
grantType("authorization_code")
            .
build();

   
try {
       
HttpHeaders headers = new HttpHeaders();
        headers.
setContentType(MediaType.APPLICATION_JSON);
       
HttpEntity<GoogleLoginRequest> httpRequestEntity = new HttpEntity<>(requestParams, headers);

       
ResponseEntity<String> apiResponseJson = restTemplate.postForEntity(configUtils.getAuthurl() + "/token", httpRequestEntity, String.class);

       
ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.
setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        objectMapper.
setSerializationInclusion(JsonInclude.Include.NON_NULL); // NULL이 아닌 값만 응답받기(NULL인 경우는 생략)
       
GoogleLoginResponse googleLoginResponse = objectMapper.readValue(apiResponseJson.getBody(), new TypeReference<GoogleLoginResponse>() {});

       
String jwtToken = googleLoginResponse.getIdToken();

       
String accessToken = googleLoginResponse.getAccessToken();

       
YouTube youTube = apiExample.getYouTubeService(accessToken);

       
YouTube.Channels.List request = youTube.channels().list(Collections.singletonList("snippet,contentDetails,statistics"));

       
ChannelListResponse response = request.setMine(true).execute();


       
System.out.println("결과값");
       
System.out.println(response);
       
System.out.println(response.toString());

       
ObjectMapper mapper = new ObjectMapper();

        mapper.
setSerializationInclusion(JsonInclude.Include.NON_NULL); // NULL이 아닌 값만 응답받기(NULL인 경우는 생략)
       
YoutubeChannelList channelList = mapper.readValue(response.toString(), YoutubeChannelList.class);

       
if(channelList.getItems().size() >0){
           
System.out.println("원하는 값 id : "+ channelList.getItems().get(0).getId());
        }

       
String requestUrl = UriComponentsBuilder.fromHttpUrl(configUtils.googleInitYoutubeUrl() + "/tokeninfo").queryParam("id_token", jwtToken).toUriString();

       
String resultJson = restTemplate.getForObject(requestUrl, String.class);

       
if(resultJson != null) {

           
return ResponseEntity.ok().body(response);
        }
       
else {
           
throw new Exception("Google OAuth failed!");
        }
    }
   
catch (Exception e) {
       
e.printStackTrace();
    }

   
return ResponseEntity.badRequest().body(null);
}

 

전체적인 과정은 이렇습니다.

 

1.     로그인 성공 후 http://localhost:3030/oauth/youtube/redirect Redirect 해줍니다.

2.     로그인 완료 시 code를 부여 받는데 해당코드로 다시한번 RestTemplate를 통해서 AccessToken을 부여받을 수 있는 URl을 요청합니다. (https://oauth2.googlepais.com.tokenBody값을 담아서 보내줍니다.)

3.     AccessToken이 담긴 올바른 json결과값을 ObjectMapper를 통해서 미리 만들어 둔 객체에 매핑해줍니다.

4.     AccessToken를 이용해서 google V3 API를 사용합니다.

 

 

GoogleLoginResponse 객체는

 

import lombok.*;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class GoogleLoginResponse {
   
private String accessToken; // 애플리케이션이 Google API 요청을 승인하기 위해 보내는 토큰
   
private String expiresIn;   // Access Token의 남은 수명
   
private String refreshToken;    // 새 액세스 토큰을 얻는 데 사용할 수 있는 토큰
   
private String scope;
   
private String tokenType;   // 반환된 토큰 유형(Bearer 고정)
   
private String idToken;

}

 

이렇게 짜여있습니다.

필드 값은 이름 그대로 사용했기 때문에 그대로 준비해서 사용해주시면 됩니다.

 

@RequiredArgsConstructor
@Log4j2
@Component
public class ApiExample {

   
@Value("${mygoogle.apiKey}")
   
private String apiKey;

   
@Value("${mygoogle.clientid}")
   
private String clientid;

   
@Value("${mygoogle.clientsecret}")
   
private String clientsecret;

   
@Value("${mygoogle.clientredirect}")
   
private String redirecturl;

   
private static final Collection<String> SCOPES =
           
Arrays.asList("https://www.googleapis.com/auth/youtube.readonly",
                   
"https://www.googleapis.com/auth/userinfo.profile",
                   
"https://www.googleapis.com/auth/userinfo.email");

   
private static final String APPLICATION_NAME = "웹 클라이언트 1";
   
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();


   
private final String client = "{\n" +
           
\"installed\": {\n" +
           
"    \"client_id\": \""+clientid+"\",\n" +
           
"    \"client_secret\": \""+clientsecret+"\",\n" +
           
"    \"redirect_uri\": \""+redirecturl+"\"\n" +
           
"}\n" +
           
"}";

   
/**
     * Create an authorized Credential object.
     *
     *
@return an authorized Credential object.
     *
@throws IOException
    
*/
   
public Credential authorize(final NetHttpTransport httpTransport) throws IOException {
       
// Load client secrets.
       
InputStream in = ApiExample.class.getResourceAsStream(client);
       
GoogleClientSecrets clientSecrets =
               
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
       
// Build flow and trigger user authorization request.
       
GoogleAuthorizationCodeFlow flow =
               
new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
                        .
build();
       
LocalServerReceiver receiver = new LocalServerReceiver.Builder()
                .
setPort(4040)
                .
build();
       
Credential credential =
               
new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
       
return credential;
    }


   
/**
     * Build and return an authorized API client service.
     *
     *
@return an authorized API client service
     *
@throws GeneralSecurityException, IOException
     */
   
public YouTube getService() throws GeneralSecurityException, IOException {
       
final NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

       
Credential credential = authorize(httpTransport);
       
return new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
                .
setApplicationName(APPLICATION_NAME)
                .
build();
    }


   
public YouTube getYouTubeService(String accessToken) throws GeneralSecurityException, IOException {
       
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

       
// 자료 맞춘거
       
InputStream inputStream = new ByteArrayInputStream(client.getBytes());

       
GoogleClientSecrets clientSecrets = GoogleClientSecrets
               
.load(JSON_FACTORY, new InputStreamReader(inputStream));

       
// Flow
       
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
                .
build();

       
// Use the access token to create the credential object
       
TokenResponse response = new TokenResponse();

       
// accessToken 반드시 필요
       
response.setAccessToken(accessToken);

       
Credential credential = flow.createAndStoreCredential(response, null);

       
// Build and return the YouTube object
       
return new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
                .
setGoogleClientRequestInitializer(new YouTubeRequestInitializer(apiKey))
                .
setApplicationName(APPLICATION_NAME)
                .
build();
    }

}

 

 

 

참고로 테스트해보는 사이트에서 client가 어떤 내용이 담겨야 하는지 설명이 나와있지 않아서 이렇게 따로 문서를 보면서 찾아냈습니다.




해당 코드를 통해서 API를 요청할 수 있습니다.

 

1.     아까 캡처해 놓았던 client를 참고해 InputStream자료형으로 담아줍니다.

2.     CodeFlow를 통해서 올바른 Credential을 받아올 수 있습니다.

3.     그리고 아까 로그인 완료와 token요청을 통해 받아 둔 accessTokenresponse에 담아줍니다.

4.     중요한점은 128줄을 보시면 apiKey가 필요하다는 걸 알 수 있습니다. 발급 받아 둔 걸 사용해 줍니다.

 

필요한 요소가 모두 갖춰졌다면 올바르게 YouTube 자료형이 반환 됩니다.

 



이제 다시 Controller에 와서 올바르게, 에러가 없이 YouTube 객체를 받아와 졌다면 이제 자유롭게 요청하면 됩니다.

 

저는 전 게시글에서 말한 것처럼 로그인 유저의 채널 정보를 받아오고 싶기 때문에 위 코드처럼 작성하면됩니다.


(위 코드가 이제 해당 UI 였다는 걸 알 수 있습니다.)

결과



이렇게 ID값이 잘 받아온 걸 알 수 있습니다.

API V3 라이브러리를 가져오면 다양한 API들을 요청할 수 있는 걸 알 수 있습니다.



긴 글 봐주셔서 감사합니다!