PocketでOAuth2認証を行う方法

PocketでOAuth2認証を行う方法

Posted at April 1,2014 1:55 AM
Tag:[OAuth, Pocket]

PocketでOAuth2認証を行う方法を紹介します。

OAuth2による認証(クリックで拡大)
OAuth2による認証

このエントリーは「Pocket Authentication API Documentation」の内容を元にしています。誤り等ありましたらどこかでつぶやいてください。

記事の最後にPHPのサンプルコードも掲載しています。

1.一般的なガイドライン

  • Pocket Authentication APIはHTTPSを利用しなければなりません
  • Pocket Authentication APIはPOSTメソッドを利用しなければなりません(GETは未サポート)
  • Content-Typeヘッダでリクエストのフォーマットを示す。Pocket Authentication APIは2つのフォーマットをサポートする。
    • application/x-www-form-urlencoded(デフォルト)
    • application/json
  • X-Acceptヘッダーは、レスポンスで受信したい形式を示す。ポケット認証APIの2つの形式をサポートする。
    • application/x-www-form-urlencoded(デフォルト)
    • application/json

2.ステップ1:コンシューマキーの取得

Pocketにアプリケーションを登録する」の記事を参考にコンシューマキーを取得します。

3.ステップ2:リクエストトークンの取得

URL

https://getpocket.com/v3/oauth/request

パラメータ

  • コンシューマキー
  • リダイレクトURI:認証プロセスが完了したときに呼び出されるURIです。このURLでアプリケーションに直接戻る必要があります。iOSとAndroidでリダイレクトURIを設定する方法はプラットフォーム固有の注意事項を参照。
  • 状態(オプション)

以下にサンプルを示します。いくつかのHTTPヘッダは簡略化するため省略されています。

HTTPリクエストのサンプル(x-www-form-urlencoded)

POST /v3/oauth/request HTTP/1.1
Host: getpocket.com
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Accept: application/x-www-form-urlencoded
 
consumer_key=1234-abcd1234abcd1234abcd1234&
redirect_uri=pocketapp1234:authorizationFinished

HTTPレスポンスのサンプル(x-www-form-urlencoded)

HTTP/1.1 200 OK
Content-Type: application/x-www-form-urlencoded
Status: 200 OK
 
code=dcba4321-dcba-4321-dcba-4321dc

HTTPリクエストのサンプル(JSON)

POST /v3/oauth/request HTTP/1.1
Host: getpocket.com
Content-Type: application/json; charset=UTF-8
X-Accept: application/json
 
{"consumer_key":"1234-abcd1234abcd1234abcd1234",
"redirect_uri":"pocketapp1234:authorizationFinished"}

HTTPレスポンスのサンプル(JSON)

HTTP/1.1 200 OK
Content-Type: application/json
Status: 200 OK
 
{"code":"dcba4321-dcba-4321-dcba-4321dc"}

リクエストトークン(レスポンスの中にあるcode=XXX)はステップ5で使うために保持する必要があります。

Webアプリケーションの場合はセッションあるいは他の永続的状態に関連づける必要があります。

HTTPレスポンスが200の場合は成功です。

エラーが発生した場合、HTTPステータスコードおよびHTTPヘッダーのX-Error-CodeとX-Errorフィールドに詳細が含まれます。

ステータスコードX-Error-CodeX-Error
400138コンシューマキーが誤っている
400140リダイレクトURIが誤っている
403152無効なコンシューマキー
50X199Pocketサーバの問題

4.ステップ3:承認を継続するためのユーザーへのリダイレクト

リクエストトークン取得後、アプリケーションのリクエストトークンを認可するためにユーザーにリダイレクトする必要があります。

リダイレクトするときは、2つの情報を含める必要があります。

  • request token
  • redirect_uri

redirect_uriは承認を完了したときに呼び出されるURLです。このURLはアプリケーションに直接戻る必要があります。

pocket-oauth-v1:///authorize?request_token=YOUR_REQUEST_TOKEN&redirect_uri=YOUR_REDIRECT_URI

上のようなURLスキームを検出できないプラットフォームの場合、次のURLにリダイレクトしてください。

https://getpocket.com/auth/authorize?request_token=YOUR_REQUEST_TOKEN&redirect_uri=YOUR_REDIRECT_URI

PocketはAuthorizationページのモバイルおよびデスクトップ版を持っていて、ユーザーが使用しているデバイスの種類を正しく検出し、それに応じてリダイレクトします。

アプリケーション内のWeb画面などにこのページを提示してはいけません。
新しいタブにそのデフォルトブラウザを介してURLにユーザーを送ってください。

利用者が到着したときに関係なく、ポケットのアプリやWebサイトにユーザーを送信するかどうかの、3つのいずれかの処理が行われます。

  1. Pocketにサインインして、アプリを承認している場合は提供されているredirect_uriが呼び出されます
  2. Pocketにサインインして、アプリを承認していない場合は、承認要求画面を表示します。ユーザーが承認したあと、提供されたredirect_uriが呼び出されます。
  3. Pocketにサインインしていない場合、まずサインインが要求されます。そのアカウントで既にアプリケーションへのアクセスを許可している場合redirect_uriがすぐに呼び出されます。それ以外の場合、ユーザーは認証要求画面が表示されます。

テスト中に

http://getpocket.com/connected_accounts

にアクセスすることによって、テストユーザーに関連付けられたトークンをクリアできます。

補足:アクセスすると「接続済みのサービスとアプリケーション」画面が表示されるので、「第三者アプリケーション」の「アクセスを削除」をクリックします。

(クリックで拡大)
接続済みのサービスとアプリケーション

5.ステップ4:Pocketからコールバックを受け取る

ユーザーがアプリケーションのリクエストトークンを許可(または拒否)したとき、あなたのコールする/v3/oauth/requestを提供することで、リクエストURIを開き、ユーザーをアプリケーションに戻します。

6.ステップ5:リクエストトークンをアクセストークンに変換

アプリケーションと一緒にPocketを承認する最後のステップは、リクエストトークンをアクセストークンに変換することです。アクセストークンは、Pocket APIを使用するユーザー固有のトークンです。

URL

https://getpocket.com/v3/oauth/authorize

パラメータ

  • consumer_key:ステップ1のコンシューマキー
  • code:ステップ2のリクエストトークン(codeフィールド)

HTTPリクエストのサンプル(x-www-form-urlencoded)

POST /v3/oauth/authorize HTTP/1.1
Host: getpocket.com
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Accept: application/x-www-form-urlencoded
 
consumer_key=1234-abcd1234abcd1234abcd1234&
code=dcba4321-dcba-4321-dcba-4321dc

HTTPレスポンスのサンプル(x-www-form-urlencoded)

HTTP/1.1 200 OK
Content-Type: application/x-www-form-urlencoded
Status: 200 OK
 
access_token=5678defg-5678-defg-5678-defg56&
username=pocketuser

HTTPリクエストのサンプル(JSON)

POST /v3/oauth/authorize HTTP/1.1
Host: getpocket.com
Content-Type: application/json; charset=UTF-8
X-Accept: application/json
 
{"consumer_key":"1234-abcd1234abcd1234abcd1234",
"code":"dcba4321-dcba-4321-dcba-4321dc"}

HTTPレスポンスのサンプル(JSON)

HTTP/1.1 200 OK
Content-Type: application/json
Status: 200 OK
 
{"access_token":"5678defg-5678-defg-5678-defg56",
"username":"pocketuser"}

usernameは、アプリケーションで認証されたユーザのユーザ名を伝えるために提供されます。

HTTPレスポンスが200の場合は成功です。

エラーが発生した場合、HTTPステータスコードおよびHTTPヘッダーのX-Error-CodeとX-Errorフィールドに詳細が含まれます。

ステータスコードX-Error-CodeX-Error
400138コンシューマキーが誤っている
403152無効なコンシューマキー
400181無効なリダイレクトURI
400182codeが誤っている
400185codeがみつかりません
403158ユーザーがcodeを拒否
403159すでに使われているcode
50X199Pocketサーバの問題

7.ステップ6:Pocketへの認証済みリクエスト

Pocketのアクセストークンを持っていれば、Pocket V3 APIで認証済みのリクエストを行えます。これを行うには、任意のAPIリクエストに2つのパラメータを追加します。

consumer_key: ステップ1のコンシューマキー
access_token: ステップ5のアクセストークン

HTTPリクエストのサンプル(JSON)

POST /v3/add HTTP/1.1
Host: getpocket.com
Content-Type: application/json; charset=UTF-8
X-Accept: application/json
 
{"url":"http:\/\/pocket.co\/s8Kga",
"title":"iTeaching: The New Pedagogy (How the iPad is Inspiring Better Ways of 
Teaching)",
"time":1346976937,
"consumer_key":"1234-abcd1234abcd1234abcd1234",
"access_token":"5678defg-5678-defg-5678-defg56"}

HTTPレスポンスのサンプル(JSON)

HTTP/1.1 200 OK
Content-Type: application/json
Status: 200 OK
 
{"status":1}

8.その他

セキュリティ目的のため、ブラウザのポップアップを利用するとアクセスが無効になる可能性があります。

9.サンプルコード

ここでは認証に次の2つのファイルを用意しています。

  • ①リクエストトークン取得&リダイレクト用PHP
  • ②アクセストークン取得用PHP

リクエストトークン取得&リダイレクト用PHP

<?php
$url = 'アクセストークン取得用PHPのURL';
$consumer_key = 'コンシューマキー';
$request_token_url = 'https://getpocket.com/v3/oauth/request';
$redirect_url = 'https://getpocket.com/auth/authorize?request_token=';
 
// ステップ2:リクエストトークンの取得
$opt = array(
    'http' => array(
        'method' => 'POST',
        'content' => http_build_query(
            array(
                'consumer_key' => $consumer_key,
                'redirect_uri' => $url,
            )
         ),
     )
);
$response = @file_get_contents($request_token_url, false, stream_context_create($opt));
$request_token = explode('=', $response);
 
// ステップ3:承認を継続するためのユーザーへのリダイレクト
header('Location: ' . $redirect_url . $request_token[1] . '&redirect_uri=' . $url;
?>

アクセストークン取得用PHP

<?php
$consumer_key = 'コンシューマキー';
$authorize_url = 'https://getpocket.com/v3/oauth/authorize';
$api_url = 'https://getpocket.com/v3/get';
 
// ステップ5:リクエストトークンをアクセストークンに変換
$opt = array(
    'http' => array(
        'method' => 'POST',
        'content' => http_build_query(
            array(
                'consumer_key' => $consumer_key,
                'code' => $_REQUEST["code"],
            )
        ),
    )
);
$response = @file_get_contents($authorize_url, false, stream_context_create($opt));
$param = explode('&',$response);
$access_token = explode('=', $param[0]);
$username = explode('=', $param[1]); // usernameは本サンプルでは未使用
 
// ステップ6:Pocketへの認証済みリクエスト
$opt = array(
    'http' => array(
        'method' => 'POST',
        'content' => http_build_query(
            array(
                'consumer_key' => $consumer_key,
                'access_token' => $access_token[1],
            )
        ),
    )
);
$response = @file_get_contents($api_url, false, stream_context_create($opt));
var_dump($response);
?>

それぞれのファイルの赤色で示した部分を編集したあと、任意のPHPファイル名で保存し、ブラウザから①のファイルにアクセスすれば冒頭のスクリーンショットが表示され、許可をクリックすれば②のファイルにリダイレクトされ、次のような結果が表示されます。

認証済リクエスト結果

認証済みリクエストは、サンプルとして「https://getpocket.com/v3/get」を設定しているので、任意のAPIのURLおよび必要なパラメータを適宜追加してください。

関連記事
zenback
人気エントリー
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)