web-dev-qa-db-ja.com

Google Calendar APIv3-ハードコードされた認証情報で認証する

ユーザーが特定のイベントをプライベートGoogleカレンダーに追加できるようにするPHPアプリケーションを作成しています。カレンダーは私が所有しており、PHP固定の資格情報を使用してカレンダーAPIと通信します(誰でもWebサイトのフォームを使用してイベントを追加できますが、カレンダー自体は公開されません)。

私が読んだことから、これはv1APIのClientLoginを使用して可能です。ただし、v3 APIでは、使用可能なオプションはOAuth2.0またはAPIキーです。 APIキーの使用は、認証を必要としないリクエストにのみ使用できるため、機能していないようです。また、OAuthは、ユーザーが認証を行う必要がないため、正しくないようです。独自のカレンダーにアクセスしますが、私のアプリケーションが使用するカレンダーです。

プログラムでOAuthトークンを取得することを考えましたが、OAuthダイアログはキャプチャを使用できるため、遅かれ早かれ壊れることになります。

これは、そのような標準的なユースケースのようです。ユーザーが事前定義された方法で単一のカレンダーを操作できるWebアプリケーションですが、v3APIでそれを実現する方法に関するドキュメントが見つかりません。誰か助けてもらえますか?

19
user1063949

開発者キー(APIキー)とOAuth2の両方を使用する必要があります。開発者キーは、ソフトウェアを作成したユーザーを認証し、ユーザーごとではなく開発者ごとのクォータなどに使用されます。 OAuth2はユーザー認証用であり、非公開カレンダーにアクセスする必要があります。

OAuth2には、セッショントークンを生成できる更新トークンがあります。これは、認証を受けるためにOAuth画面をスクリーンスクレイピングする必要がないことを意味します。これを取得するには、小さなコマンドラインを記述します。アプリケーション、または1回限りのPHPページを使用します。

  1. Google Api Console APIアクセスに移動します
  2. 新しいクライアントIDを生成し、[インストール済みアプリケーション]を選択します(ユーザーではなくサーバーを認証するため)
  3. コンソールアプリを使用するか、1回限りのPHPページ認証OAuthとGoogleアカウント(アクセスしたいカレンダーのあるアカウント)を使用して)
  4. 認証からの戻りには、更新トークン(renewまたはrefreshなどと呼ばれる)が必要です。この文字列を保存して、PHPサイトで利用できるようにします。
  5. サービスにアクセスする必要がある場合、OAuthライブラリにはrenew/refresh呼び出しが必要です。以下に.Netを使用した例があります。

private IAuthorizationState CreateAuthorization(NativeApplicationClient arg)
 {
   // Get the auth URL:
   IAuthorizationState state = new AuthorizationState(new[] { AdsenseService.Scopes.AdsenseReadonly.GetStringValue() });
   state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
   if (refreshToken.IsNotNullOrEmpty()) // refreshToken you stored in step 4
   {
     try
     {
       state.RefreshToken = refreshToken;
       if (arg.RefreshToken(state))     // This is calling out to the OAuth servers with the refresh token getting back a session token, returns true if successful.
       {
         if (state.RefreshToken != refreshToken) // if the refresh token has changed, save it.
         {
           PersistRefreshToken(authorization.RefreshToken);
         }
         return this.authorization = state; // Retain the authorization state, this is what will authenticate your calls.
       }
     }
     catch (ProtocolException ex) {...}

更新されたAuthorisationStateを使用して、APIへの呼び出しを認証できます。この状態は、有効期限が切れてから更新できるまで、何度も使用できます。アプリケーションをユーザーとしてではなく自分自身として認証しているため、このAuthorisationStateはすべてのセッションで共有できます。現在のAuthorisationStateと更新トークンの両方をサーバーに安全に保持し、クライアントに送信しないでください。応答の一部としてこれらを送信した場合、クライアントはコードアプリケーションと同じ特権を持ちます。

13
David Waters

私はそれがあなたがやりたいことの「公式」だと思う解決策を見つけました。

まず、GoogleAPI「インストールされたアプリケーションのクライアントID」をアクティブ化する必要があります。

Google APIコンソールに移動し、プロジェクトを作成します。

次に、カレンダーをアクティブにします。

[APIアクセス]オプションに移動し、[作成OAuth2.0クライアント]ボタンを使用します。

製品に名前(および必要に応じてロゴ)を付けます。 「次へ」をクリックします。

「インストールされたアプリケーション」オプションを選択し、「クライアントIDの作成」をクリックします。

これで、アクセスが構成されました。ここで、いくつかのコードが必要になります。それらを取得するには:

*「認証コード」。これを取得するには、次の情報が必要です。

範囲: https://www.google.com/calendar/feeds/ (カレンダーAPIにアクセスする場合。他にも見つけることができますOAuth 2.0 Playgroundでそれらを)

CLIENT_ID:GoogleAPIコンソールのAPIアクセスセクションにあります。

REDIRECT_URI:同じ場所で入手してください。

次に、次のコードをファイルにコピーし、値を変数に入れ、コード(php -q script_name.php)を実行して、印刷されたURLに移動します。

<?php
$scope         =   '';
$client_id      =   '';
$redirect_uri   =   '';

$params = array(
                    'response_type' =>   'code',
                    'client_id'     =>   $client_id,
                    'redirect_uri'  =>   $redirect_uri,
                    'scope'         =>   $scope
                    );
$url = 'https://accounts.google.com/o/oauth2/auth?' . http_build_query($params);        
echo $url."\n";
?>

Webページで、アクセスを許可するように求められます。それを行うと、認証コードであるコードを取得します。

*「リフレッシュコード」。それを取得するには、次のものが必要です。

以前に使用したデータと、「クライアントID」と「リダイレクトURI」の間のAPIコンソールの「クライアントシークレット」コード。

前と同じように、次のコードをコピーして、変数を配置します(コードフィールドは認証コードです)。実行すると、結果は「リフレッシュトークン」です。

<?php
$url = 'https://accounts.google.com/o/oauth2/token';
$post_data = array(
                    'code'          =>   '',
                    'client_id'     =>   '',
                    'client_secret' =>   '',
                    'redirect_uri'  =>   '',
                    'grant_type'    =>   'authorization_code',
                    );
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($ch);
$token = json_decode($result);

echo $token->refresh_token . "\n";
?>

現時点では、必要なものはすべて揃っています。いつか認証コードを変更する場合は注意してください。新しいキーを取得する必要があります。

カレンダーサービスにアクセスするには、次の例を示します。使用する前に変数値を変更します。この例では、主要なカレンダーイベントを取得しますが、カレンダーAPI( http://code.google.com/intl/ca/apis/calendar/v3/)で任意のアドレスを変更できます。 get_started.html#background_operations

    <?php
    $scope         =   'https://www.google.com/calendar/feeds/';
    $client_id      =   '';
    $client_secret  =   '';
    $redirect_uri   =   '';


    $refresh_token  =   '';

    $token_url = 'https://accounts.google.com/o/oauth2/token';
    $post_data = array(
                        'client_secret' =>   $client_secret,
                        'grant_type'    =>   'refresh_token',
                        'refresh_token' =>   $refresh_token,
                        'client_id'     =>   $client_id
                        );
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $token_url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);
    $token_object = json_decode($result);
    $access_token = $token_object->access_token;

    // Get the results
    $rest_url = 'https://www.googleapis.com/calendar/v3/calendars/primary/events';
    $header = "Authorization: OAuth " . $access_token;

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
    curl_setopt($ch, CURLOPT_URL, $rest_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $rest_result = curl_exec($ch);

    print_r(json_decode($rest_result));
    ?>

まず、スクリプトは1時間有効な「アクセストークン」を要求します。次に、スクリプトはRESTサービス(カレンダースコープ内の任意のサービス)を取得し、ヘッダーでアクセストークンを送信します。スクリップで最高の速度を与えるには、アクセストークンを3600秒より古くなるまでキャッシュに保存することをお勧めします。このようにして、スクリプトは2つの呼び出しのうちの1つを回避します。

チップ:

OAuth 2.0 Playgroundにアクセスして、OAuthプロセスで送信されるすべての情報を理解してください。それは私を大いに助けました

EricNagelのブログへの投稿で解決策がわかりました。すべてのメリットは彼にあります。十分な「評判」がないため、リンクできません。

28
Roger Veciana

Googlephpライブラリでも使用できます。 $client->setAccessToken()関数のアクセストークンは、次のようにフォーマットする必要があります。

$at= '{"access_token":"' . $access_token . '",' .
      '"token_type":"Bearer",' .
      '"expires_in":3600,' .
      '"refresh_token":"' . $refresh_token . '",',
      '"created":' . time() . '}';

ここで、$access_tokenはユーザーが見つけたアクセストークンであり、$refresh_tokenは更新トークンです。役に立たないsimple.phpgoogleの例でテストしました。

その場合、認証は次のようになります。

$client->setAccessToken($at);
2
yado