web-dev-qa-db-ja.com

Google API PHPオフラインアクセス、「invalid_grant:コードは既に利用されています」

ユーザーが承認を取り消すまでGoogleクライアントを永続的に承認する方法?

Googleカレンダーに接続するアプリを作成しようとしています。 PHPで実行する必要があるため、Googleが提供するGoogle API PHPクライアントを使用しています。

ユーザーがセッションに参加していないときに機能するように、アプリにはオフラインアクセスが必要です。このアプリは、ユーザーが自分のカレンダーをWebサイトなどで公開して管理および表示できるようにすることを目的としています。

サービスメソッド(クライアントIDとクライアントシークレットを使用)を使用して、Googleコンソールで資格情報を作成しました。 Google APIクライアントを使用して、ユーザーからの承認もリクエストしました。新しいブラウザウィンドウを開き、ユーザーが承認すると、Googleから承認コードが返されます。このコードを取得して保存し、それを使用してクライアントを認証します。クライアントはGoogleカレンダーに正常に接続し、データを交換します。

今、私はこれが期限切れになるトークンであることを理解しました。私が設定したオフラインアクセスを使用しない限り。ただし、数分以内にエラーが発生します:Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.

これは、クライアントの接続に使用するコードです。

$client = new \Google_Client();
$client->setApplicationName( 'My App' );
$client->setScopes( array( \Google_Service_Calendar::CALENDAR ) );
$client->setClientId( $this->google_client_id );
$client->setClientSecret( $this->google_client_secret );
$client->setRedirectUri( $this->google_client_redirect );
$client->setAccessType( 'offline' );

if ( $code = $this->google_client_auth ) {

    try {

        $client->authenticate( $code );

    } catch( \Exception $e ) {
            var_dump( $e );
    }    

}

return new \Google_Service_Calendar( $client );

これはクラス内のメソッドです。

クライアントIDとクライアントシークレットは、アプリの設定に保存されます。

また、ユーザーから返されたコードを設定に保存していますが、これが間違っていると思いますか?Google OAuthウィンドウへのリンクを別のウィンドウに入れていますメソッド(同じクライアントIDとシークレットを使用し、オフラインメソッドも設定します。)承認を取得することは機能します。カレンダーにアクセスできます。

16
unfulvio

Googleの認証サーバーが返すコードまたはトークンには3つのタイプがあります。

  1. 認証コード
  2. アクセストークン
  3. 更新トークン。

認証コード

ユーザーが認証フォームをクリックして、アプリケーションへのアクセスを許可したとき。 Googleから認証コードが返されます。このコードを取得して、アクセストークンと更新トークンに交換する必要があります。このコードは、もう一度使用してエラーメッセージが表示される場合に1回だけ使用されます。

invalid_grant:コードはすでに利用されています。

アクセストークン

アクセストークンは、このトークンが送信するすべてのリクエストとともに送信されるAPIにアクセスするために使用されます。アクセストークンは短命で1時間動作し、その後動作しなくなります

トークンの更新

リフレッシュトークンは、サーバーのどこかに保存する必要があります。アクセストークンの有効期限が切れると、更新トークンを使用して新しいアクセストークンを取得できます。

問題は、あなたが役に立たない認証コードを保存していることです。更新トークンを見つけて保存する必要があります。

28
DaImTo