質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

YouTube API

YouTube APIはYouTubeのビデオコンテンツと機能性をウェブサイト、アプリケーション、デバイスに統合することを可能にします。

Q&A

解決済

1回答

2858閲覧

アクセストークンが取得出来ない

study_111

総合スコア82

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

YouTube API

YouTube APIはYouTubeのビデオコンテンツと機能性をウェブサイト、アプリケーション、デバイスに統合することを可能にします。

0グッド

0クリップ

投稿2020/07/06 14:38

編集2020/07/06 14:40

前提・実現したいこと

YoutubeDataApiV3のサンプルコードを元に、動画アップロード処理を記述したのですが、アクセストークンを取得する部分で、NULLとなってしまい、先の処理が行えない状況です。

発生している問題・エラーメッセージ

NULLとなってしまっているのは、以下の部分です。

var_dump($client->getAccessToken());

該当のソースコード

以下は、PHPコードの全文になります。

php

1<?php 2require_once __DIR__ . '/vendor/autoload.php'; 3session_start(); 4 5if ($_SERVER['REQUEST_METHOD'] == 'GET') { 6 echo('getリクエストです'); 7 exit(); 8} 9 10$err_msg = array(); 11$title = ''; 12$description = ''; 13$tag = ''; 14$tag_array = array(); 15$category_id = ''; 16 17// $tag_array[0] = 'aaa'; 18// var_dump($tag_array); 19//拡張子取得 20function getExt($filename) 21{ 22 return pathinfo($filename, PATHINFO_EXTENSION); 23} 24// echo(__DIR__ ); 25 26 27 28//タイトル取得 29if(isset($_POST['title'])){ 30 $title = $_POST['title']; 31 // print($comment); 32} 33 34//説明 35if(isset($_POST['description'])){ 36 $description = $_POST['description']; 37 // print($comment); 38} 39 40 41//タグ 42if(isset($_POST['tag'])){ 43 // echo('sss'); 44 $tag = $_POST['tag']; 45 // echo($tag); 46 if (mb_strlen($tag, 'UTF-8') > 500){ 47 $err_msg[] = 'タグに登録出来る文字数は500文字以内です'; 48 }else{ 49 $tag_array = explode(',',$tag); 50 // $tag_array = array_filter($tag_array,'strlen'); 51 $tag_array = array_filter($tag_array,function($x){ 52 return preg_match("/\S+/misu",$x); 53 }); 54 55 // var_dump($tag_array[3]); 56 $tag_array = array_unique($tag_array); 57 // var_dump($tag_array); 58 } 59} 60 61if(isset($_POST['category'])){ 62 $category_id = $_POST['category']; 63 // var_dump($category_id); 64} 65 66 67if(isset($_FILES['certification_file']['tmp_name'])){ 68 // echo('jsonファイルは存在します'); 69 // echo($_FILES['certification_file']['tmp_name']); 70 $ext = getExt($_FILES['certification_file']['name']); 71 // echo(__LINE__); 72 // echo($ext); 73 74 if ($ext == "json"){ 75 // echo("jsonファイルです。"); 76 $certification_tmpfile = $_FILES['certification_file']['tmp_name']; 77 $certification_filename = "./credentials/" . date("YmdHis"); 78 $certification_filename .= mt_rand(); 79 // $certification_filename = "./credentials/". $_FILES['certification_file']['name']; 80 $certification_filename .= '.' . $ext; 81 if (is_uploaded_file($certification_tmpfile)) { 82 83 if ( move_uploaded_file($certification_tmpfile , $certification_filename)) { 84 echo $certification_filename . "をアップロードしました。"; 85 } else { 86 echo "ファイルをアップロードできません。"; 87 } 88 89 } else { 90 echo "ファイルが選択されていません。"; 91 } 92 }else{ 93 echo("credentials.jsonファイルではありません。"); 94 } 95 96 // echo($_FILES['certification_file']['type']); 97 // echo($certification_filename); 98 // echo "\n"; 99 100 // echo($certification_tmpfile); 101} 102 103if(isset($_FILES['movie_file']['tmp_name'])){ 104 105 $ext = getExt($_FILES['movie_file']['name']); 106 107 $movie_tmpfile = $_FILES['movie_file']['tmp_name']; 108 109 $movie_filename = "./movies/" . date("YmdHis"); 110 $movie_filename .= "." . $ext; 111 112 if (is_uploaded_file($movie_tmpfile)) { 113 114 if ( move_uploaded_file($movie_tmpfile , $movie_filename)) { 115 echo $movie_filename . "をアップロードしました。"; 116 } else { 117 echo "ファイルをアップロードできません。"; 118 } 119 } else { 120 echo "ファイルが選択されていません。"; 121 } 122 123 // echo($movie_tmpfile); 124} 125 126// echo($movie_filename)."\n"; 127 128 129 130$url = $certification_filename; 131$json = file_get_contents($url); 132$json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 133// echo($json); 134$cert_arr = json_decode($json,true); 135// var_dump($cert_arr); 136 137 138if (!file_exists(__DIR__ . '/vendor/autoload.php')) { 139 throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"'); 140} 141 142$OAUTH2_CLIENT_ID = $cert_arr['web']['client_id']; 143$OAUTH2_CLIENT_SECRET = $cert_arr['web']['client_secret']; 144echo($OAUTH2_CLIENT_ID); 145echo '<br>'; 146echo($OAUTH2_CLIENT_SECRET); 147// echo($_SERVER['HTTP_HOST'] ); 148$client = new Google_Client(); 149// var_dump($OAUTH2_CLIENT_ID); 150// var_dump($OAUTH2_CLIENT_SECRET); 151$client->setClientId($OAUTH2_CLIENT_ID); 152$client->setClientSecret($OAUTH2_CLIENT_SECRET); 153$client->setScopes('https://www.googleapis.com/auth/youtube'); 154$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'], 155 FILTER_SANITIZE_URL); 156$client->setRedirectUri($redirect); 157 158// 使用するサービスを作成 159$youtube = new Google_Service_YouTube($client); 160 161// var_dump($youtube); 162$tokenSessionKey = 'token-' . $client->prepareScopes(); 163if (isset($_GET['code'])) { 164 if (strval($_SESSION['state']) !== strval($_GET['state'])) { 165 die('The session state did not match.'); 166 } 167 $client->authenticate($_GET['code']); 168 $_SESSION[$tokenSessionKey] = $client->getAccessToken(); 169 header('Location: ' . $redirect); 170} 171if (isset($_SESSION[$tokenSessionKey])) { 172 // echo(__LINE__); 173 $client->setAccessToken($_SESSION[$tokenSessionKey]); 174} 175 176var_dump($client->getAccessToken()); 177// echo(__LINE__); 178// Check to ensure that the access token was successfully acquired. 179if ($client->getAccessToken()) { 180 $htmlBody = ''; 181 echo(__LINE__); 182 try{ 183 184 //アップロードするファイルパスへ置き換える 185 $videoPath = $movie_filename; 186 187 // Create a snippet with title, description, tags and category ID 188 // Create an asset resource and set its snippet metadata and type. 189 // This example sets the video's title, description, keyword tags, and 190 // video category. 191 192 $snippet = new Google_Service_YouTube_VideoSnippet(); 193 $snippet->setTitle($title); 194 $snippet->setDescription($description); 195 $snippet->setTags($tag_array); 196 197 // Numeric video category. See 198 // https://developers.google.com/youtube/v3/docs/videoCategories/list 199 $snippet->setCategoryId($category_id); 200 201 // Set the video's status to "public". Valid statuses are "public", 202 // "private" and "unlisted". 203 $status = new Google_Service_YouTube_VideoStatus(); 204 205 //公開ステータスは「非公開」に設定 206 $status->privacyStatus = "private"; 207 208 // Associate the snippet and status objects with a new video resource. 209 $video = new Google_Service_YouTube_Video(); 210 $video->setSnippet($snippet); 211 $video->setStatus($status); 212 213 // Specify the size of each chunk of data, in bytes. Set a higher value for 214 // reliable connection as fewer chunks lead to faster uploads. Set a lower 215 // value for better recovery on less reliable connections. 216 $chunkSizeBytes = 1 * 1024 * 1024; 217 218 // Setting the defer flag to true tells the client to return a request which can be called 219 // with ->execute(); instead of making the API call immediately. 220 $client->setDefer(true); 221 222 // Create a request for the API's videos.insert method to create and upload the video. 223 $insertRequest = $youtube->videos->insert("status,snippet", $video); 224 var_dump($insertRequest); 225 // Create a MediaFileUpload object for resumable uploads. 226 $media = new Google_Http_MediaFileUpload( 227 $client, 228 $insertRequest, 229 'video/*', 230 null, 231 true, 232 $chunkSizeBytes 233 ); 234 $media->setFileSize(filesize($videoPath)); 235 236 237 // Read the media file and upload it chunk by chunk. 238 $status = false; 239 $handle = fopen($videoPath, "rb"); 240 while (!$status && !feof($handle)) { 241 $chunk = fread($handle, $chunkSizeBytes); 242 $status = $media->nextChunk($chunk); 243 } 244 245 fclose($handle); 246 247 // If you want to make other calls after the file upload, set setDefer back to false 248 $client->setDefer(false); 249// echo('ssssss'); 250 251 $htmlBody .= "<h3>Video Uploaded</h3><ul>"; 252 $htmlBody .= sprintf('<li>%s (%s)</li>', 253 $status['snippet']['title'], 254 $status['id']); 255 256 $htmlBody .= '</ul>'; 257 258 } catch (Google_Service_Exception $e) { 259 $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>', 260 htmlspecialchars($e->getMessage())); 261 } catch (Google_Exception $e) { 262 $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>', 263 htmlspecialchars($e->getMessage())); 264 } 265 266 $_SESSION[$tokenSessionKey] = $client->getAccessToken(); 267 } elseif ($OAUTH2_CLIENT_ID == 'REPLACE_ME') { 268 $htmlBody = <<<END 269 <h3>Client Credentials Required</h3> 270 <p> 271 You need to set <code>$OAUTH2_CLIENT_ID</code> and 272 <code>$OAUTH2_CLIENT_ID</code> before proceeding. 273 <p> 274END; 275 } else { 276 // If the user hasn't authorized the app, initiate the OAuth flow 277 $state = mt_rand(); 278 $client->setState($state); 279 $_SESSION['state'] = $state; 280 281 $authUrl = $client->createAuthUrl(); 282 $htmlBody = <<<END 283 <h3>Authorization Required</h3> 284 <p>You need to <a href="$authUrl">authorize access</a> before proceeding.<p> 285END; 286 } 287 ?> 288<!-- // // // $url = __DIR__ . ; -->

補足情報(FW/ツールのバージョンなど)

「OAUTH2_CLIENT_ID」と「OAUTH2_CLIENT_SECRET」には、値が入っていることが、以下の部分で確認できている状況です。

echo($OAUTH2_CLIENT_ID); echo '<br>'; echo($OAUTH2_CLIENT_SECRET);

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/07/10 11:43

そもそもアクセストークン取得するための認可が動作してませんよね。 OAUTH の動きをしっていたら 1枚でやるなら GET 禁止 の時点で認可が正常終了していません
study_111

2020/07/10 12:19

サンプルコードをそのまま使用する形としたのですが、どこら辺の部分の修正、追記が必要になってくるのでしょうか?
guest

回答1

0

ベストアンサー

エラーが出る時は試しにローカルで実行してみようとした時と推測します。

残念ながら、サンプルコードそのままではローカルで実行できません。詳しいドキュメントは OAuth 2.0 Flow: Server-side web apps にでありますが、そこの情報量が多すぎて、まとめてみます。

OAuth という認証プロセスは、下記の流れで実行されます:

  1. PHPは認証リクエストをGoogleに送ります
  2. Googleはユーザーにログインを求めます
  3. Googleはユーザーがログインしてから、PHPの必要権限を求めます
  4. Googleはユーザーの同意を受けてから、ユーザーをPHPへリダイレクトします
  5. PHPはリダイレクトに含めたデータを処理し、アクセストークンを取得します

ローカルで作動できない部分はその4です。リダイレクトの必要があるので、パブリックサーバーを立ち上げ、そのサーバーでの下記の $redirect 変数の値で Google アプリコンソールに設定しないといけません。

php

1$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'], 2 FILTER_SANITIZE_URL); 3$client->setRedirectUri($redirect);

色々大変そうな設定ですが、頑張ってください。

投稿2020/07/21 09:02

YufanLou

総合スコア463

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

study_111

2020/07/21 10:12

ご回答ありがとうございます。 自分は、実行の方はローカル環境で行いました。 googleにログインしたブラウザで、formの値を入力しphp側への送信を行う形としました。 教えて下さりました「Googleはユーザーの同意を受けてから、ユーザーをPHPへリダイレクトします」こちらの部分なのですが、google側のサーバーからローカル側への通信が出来ない為に起こることなのでしょうか? 自分が思い違いをしてしまっていたら申し訳ないのですが、ローカル環境であっても外部との通信は可能ではないかと思うのですが、そういった意味ではありませんでしょうか? 勉強不足で申し訳ないのですが、何卒ご助言頂けましたら幸いです。
YufanLou

2020/07/21 10:47

ご理解はぴったりです。ただ、インターネットは複雑です。ローカル環境で外部との通信は、ローカルから外へのリクエストと外からローカルへのレスポンスに限られています。外からローカルへリクエストをできません。ローカルであるため、外からローカル環境がどこかすらわかりませんので。リダイレクトはリクエストの一種ですので、ローカルへできません。
study_111

2020/07/21 11:15 編集

ご返信ありがとうございます。 大変分かりやすいご説明で助かります。一度、パブリックなサーバーを立てて実行してみたいと思います。 いつもいつもご親切に教えて下さり、誠に感謝です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問