WebアプリでGoogle Search ConsoleのAPIを使うにあたり、リフレッシュトークン関連でハマったのでメモしておきます。
アクセストークンの取得
特に何も考えずにアクセストークンを取得すると、PHPのコードはだいたい以下の感じになると思います。
$Client = new Google_Client();
$Client->setClientId('クライアントID');
$Client->setClientSecret('クライアント シークレット');
$Client->setRedirectUri('コールバック用URI');
$Client->addScope(Google_Service_Webmasters::WEBMASTERS_READONLY);
$Service = new Google_Service_Webmasters($Client);
if (isset($_GET['code'])) {
// トークン取得
$Client->authenticate($_GET['code']);
// トークンをセッションに保存
$_SESSION['access_token'] = $Client->getAccessToken();
// リダイレクト先を設定
header('Location: 任意のURL');
exit;
}
if (isset($_SESSION['access_token'])) {
// 認証トークンをセット
$Client->setAccessToken($_SESSION['access_token']);
}
問題なく認証されれば「$_SESSION[‘access_token’]」にJSONで返ってきた認証トークンの情報が入っているのですが、リフレッシュトークンは空でした。このリフレッシュトークンがなければまた認証からやり直すことになります。
リフレッシュトークンを取得するにはパラメータが必要
調べてわかったことはクエリのパラメータを指定する必要があるみたいです。
- approval_prompt=force : 認可画面をスキップさせない。
- access_type=offline : オフラインでAPIを使う
リフレッシュトークンを使って再取得
修正したコードは以下の感じとなりました。
$Client = new Google_Client();
$Client->setClientId('クライアントID');
$Client->setClientSecret('クライアント シークレット');
$Client->setRedirectUri('コールバック用URI');
//【追加】リフレッシュトークン用に設定
$Client->setApprovalPrompt('force');
$Client->setAccessType('offline');
$Client->addScope(Google_Service_Webmasters::WEBMASTERS_READONLY);
$Service = new Google_Service_Webmasters($Client);
if (isset($_GET['code'])) {
// トークン取得
$Client->authenticate($_GET['code']);
// トークンをセッションに保存
$_SESSION['access_token'] = $Client->getAccessToken();
// リダイレクト先を設定
header('Location: 任意のURL');
exit;
}
if (isset($_SESSION['access_token'])) {
// 認証トークンをセット
$Client->setAccessToken($_SESSION['access_token']);
//【追加】リフレッシュトークンの取得
$token = json_decode($_SESSION['access_token']);
if($token->refresh_token){
$token_now = time();
$token_exp = $token->created + $token->expires_in - 1000; //単位は秒
//有効期限を見てトークンリフレッシュ
if($token_now >= $token_exp) {
$Client->refreshToken($token->refresh_token);
$_SESSION['access_token'] = $Client->getAccessToken();
}
}
}
これで無事にリフレッシュトークンを取得し、認証トークンを再発行することができました。あとはアクセスするたびに期限をチェックするのか、Ajaxでハートビートするなどして認証が切れないようにAPIを利用することが出来そうです。
参考になれば幸いです。