ホーム OAuth認証方法について

OAuth認証方法について

1. OAuthの利用目的

GREE Platformとデベロッパー様サーバー間の通信において、相互にサーバー認証を行うために、GREE Platformからデベロッパー様サーバーへの通信、およびその逆方向の通信すべてにおいて、OAuthを用いた認証が適用されます。これにより、悪意を持った攻撃者など、予期しない第三者からのアクセスを防ぎ、サーバーを守ることができます。

具体的には、双方向で交換されるHTTP通信のHTTPヘッダ部またはクエリパラメータに、生成したOAuth用のパラメータを含めて送信し、受信側はその値を同じ手法を用いて検証します。

GREE PlatformではOAuth 1.0(RFC5849)を採用しています。

2. OAuthの認証パターン

デベロッパー様側で実施していただくOAuth認証作業は、主に以下の2種類があります。

  • アプリケーションコンテナサーバーからデベロッパー様へのリクエスト時(受信したOAuthパラメータの検証)
  • デベロッパー様サーバーからAPIサーバーへのリクエスト時(OAuthパラメータを生成しHTTPヘッダに記載)

「2. デベロッパー様サーバーからAPIサーバーへのリクエスト時」においては、リクエスト方法として「リクエストタイプ」と「バッチタイプ」の2種類を提供しています。OAuthパラメータ生成時に必要なパラメータがそれぞれ異なるため、ご注意ください。

以下の章より、OAuthパラメータについて、およびOAuthパラメータを用いた具体的な検証方法・生成方法について記述していますが、OAuth用パラメータの検証、生成は手順が複雑なため、既存ライブラリの利用を推奨いたします。

※ 各言語用のライブラリの例:http://code.google.com/p/oauth/

3. OAuthパラメータについて

GREE Platformで利用しているOAuthパラメータは、以下のとおりです。

OAuthパラメータ

パラメータ名内容取得方法V※R※B※
oauth_consumer_key アプリごと固有のConsumer Key アプリ登録時にGREEが発行(サンドボックス環境と本番環境では値が異なります)
oauth_nonce リクエストごとにユニークな値 デベロッパー様サーバーで生成
oauth_timestamp UNIXタイムスタンプ デベロッパー様サーバーで生成
oauth_token アクセストークン ユーザーからデベロッパー様サーバーへのリクエストに含まれるクエリパラメータのoauth_tokenの値(初回アクセス時のみ付与されます) -
oauth_token_secret OAuth Token Secret ユーザーからデベロッパー様サーバーへのリクエストに含まれるクエリパラメータのoauth_token_secretの値(初回アクセス時のみ付与されます) -
oauth_signature_method 署名方式 HMAC-SHA1(固定)
oauth_version OAuthのバージョン 1.0(固定)
xoauth_requestor_id アプリを実行しているGREEユーザーID ユーザーからデベロッパー様サーバーへのリクエストに含まれる、クエリパラメータのopensocial_viewer_idの値(初回アクセス時のみ付与されます) - - -

※ V=「4.1. 受信したOAuthパラメータの検証方法」に必要なパラメータ

※ R=「4.2. OAuthパラメータの生成と送信方法(リクエストタイプ利用時)」に必要なパラメータ

※ B=「4.3. OAuthパラメータの生成と送信方法(バッチタイプ利用時)」に必要なパラメータ

4. OAuth生成・検証方法

OAuth生成・検証方法について4.1.から4.3.まで記載しています。必要なケースに合わせてご参照ください。

4.1. 受信したOAuthパラメータの検証方法

ユーザーからデベロッパー様サーバーへのリクエストに含まれる、クエリパラメータのOAuth Signatureの値を検証します。(初回アクセス時のみ付与されます)
検証方法としては、受信したHTTPリクエストのAuthorizationヘッダ内パラメータ、およびクエリパラメータからOAuth Signatureを生成し、受信したOAuth Signatureの値と一致するかを検証します。

手順は以下のとおりです。

4.1.1. Base Stringの生成

手順1. パラメータのソート

HTTPクエリパラメータとOAuthパラメータを合わせて、キーでアルファベット昇順に並べます。

HTTPクエリパラメータ

GETの場合 'http://HOST/?key1=value1&...&opensocial_viewer_id=0123456' のうち '?' より後ろの部分
POSTの場合 BODY部に記載される 'key1=value1&...&opensocial_viewer_id=0123456' の部分

※ ユーザーからデベロッパー様サーバーへのリクエストに含まれるクエリパラメータには、opensocial_app_id、opensocial_owner_id、opensocial_viewer_idが添付されます。(初回アクセス時のみ付与されます)

利用するOAuthパラメータ

パラメータ名サンプル値
oauth_consumer_key d308e3ccg59e
oauth_nonce CqWLVz8GkaL
oauth_timestamp 1272026745
oauth_token abcdefghi
oauth_token_secret jklmnopqrstu
oauth_signature_method HMAC-SHA1
oauth_version 1.0
手順2. パラメータの連結

すべてのキーと値を'='で連結し、各ペアを'&'で連結します。この場合、oauth_signatureは検証対象のため除外します。(opensocial_app_id、opensocial_owner_id、opensocial_viewer_idは含んでください)

生成例

生成データ key1=value1&key2=value2&oauth_consumer_key=d308e3ccg59e&oauth_nonce=CqWLVz8GkaL&
oauth_signature_method=HMAC-SHA1&oauth_timestamp=1272026745&oauth_token=abcdefghi&
oauth_token_secret=jklmnopqrstu&oauth_version=1.0&opensocial_app_id=1&
opensocial_owner_id=0123456&opensocial_viewer_id=0123456

※ 生成データに改行は含まれません。

手順3. Base Stringの生成

HTTPリクエストメソッド、アクセス先URL、手順2で生成した文字列のそれぞれをURLエンコードし、順に'&'で連結します。URLエンコード形式はRFC3986形式となります。結果、生成された文字列がBase Stringとなります。

生成例

Base String GET&http%3A%2F%2Fexamplesap.com%2Fsampleapp%2Fgadget&
key1%3Dvalue1%26key2%3Dvalue2%26oauth_consumer_key%3D
d308e3ccg59e%26oauth_nonce%3DCqWLVz8GkaL%26
oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D
1272026745%26oauth_token%3Dabcdefghi%26oauth_token_secret%3D
jklmnopqrstu%26oauth_version%3D1.0%26opensocial_app_id%3D1%26
opensocial_owner_id%3D0123456%26opensocial_viewer_id%3D0123456

※ 上記Base Stringは、HTTPリクエストメソッドがGETで、http://examplesap.com/sampleapp/gadgetにアクセスがあった場合の生成例です。

※ 生成データに改行は含まれません。

4.1.2. OAuth Signatureの生成

4.1.1.で生成したBase Stringをもとに、OAuth Signatureを生成します。

手順1. OAuth Signature生成用キーの生成

Consumer Secretとoauth_token_secretを'&'で連結し、OAuth Signature生成用のキーを作成します。

生成例

生成データ d522g1ab4ke93kdie748g719g07a781c&jklmnopqrstu
手順2. OAuth Signatureの生成

Base Stringに対して手順1.で生成したキーを用いてHMAC-SHA1アルゴリズムでハッシュ値を生成、結果をBASE64エンコードします。

生成例

キー d522g1ab4ke93kdie748g719g07a781c&jklmnopqrstu
生成元データ(Base String) GET&http%3A%2F%2Fexamplesap.com%2Fsampleapp%2Fgadget& key1%3Dvalue1%26key2%3Dvalue2%26oauth_consumer_key%3D d308e3ccg59e%26oauth_nonce%3DCqWLVz8GkaL%26 oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D 1272026745%26oauth_token%3Dabcdefghi%26oauth_token_secret%3D jklmnopqrstu%26oauth_version%3D1.0%26opensocial_app_id%3D1%26 opensocial_owner_id%3D0123456%26opensocial_viewer_id%3D0123456
生成データ RVSj/Lmwf9ulgpShxIX1sHxqC8Q=

※ ハッシュ値を計算する場合は、hash_hmac()関数(PHPの場合)を利用して生成します。

4.1.3. OAuth Signatureの照合

4.1.2.で生成されたOAuth Signature 'RVSj/Lmwf9ulgpShxIX1sHxqC8Q='と、ユーザーからデベロッパー様サーバーへのリクエストのクエリパラメータに含まれるOAuth Signatureの値を比較し、一致すれば認証は成功です。

4.2. OAuthパラメータの生成と送信方法(リクエストタイプ利用時)

APIサーバーへのリクエスト送信時に必要なAuthorizationヘッダを生成し、HTTPリクエスト内のヘッダー部に"Authorization"ヘッダとして付加します。

手順は以下のとおりです。

4.2.1. Base Stringの生成

手順1. パラメータのソート

HTTPクエリパラメータとOAuthパラメータを合わせて、キーでアルファベット昇順に並べます。

HTTPクエリパラメータ

GETの場合 'http://HOST/?key1=value1&key2=value2' のうち 'key1=value1&key2=value2' の部分
POSTの場合 BODY部に記載される 'key1=value1&key2=value2' の部分

利用するOAuthパラメータ

パラメータ名サンプル値
oauth_consumer_key d308e3ccg59e
oauth_nonce CqWLVz8GkaL
oauth_timestamp 1272026745
oauth_token abcdefghi
oauth_signature_method HMAC-SHA1
oauth_version 1.0
xoauth_requestor_id 0123456
手順2. パラメータの連結

すべてのキーと値を'='で連結し、各ペアを'&'で連結します。

生成例

生成データ key1=value1&key2=value2&oauth_consumer_key=d308e3ccg59e&oauth_nonce=CqWLVz8GkaL&
oauth_signature_method=HMAC-SHA1&oauth_timestamp=1272026745&oauth_token=abcdefghi&
oauth_version=1.0&xoauth_requestor_id=0123456

※ 生成データに改行は含まれません。

手順3. Base Stringの生成

HTTPリクエストメソッド、アクセス先URL、手順2で生成した文字列のそれぞれをURLエンコードし、順に'&'で連結します。URLエンコード形式はRFC3986形式となります。結果、生成された文字列がBase Stringとなります。

生成例

生成データ GET&http%3A%2F%2Fos.gree.net%2Fapi%2Frest%2Fpeople
%2F%40me%2F%40self&key1%3Dvalue1%26key2%3Dvalue2%26
oauth_consumer_key%3Dd308e3ccg59e%26oauth_nonce%3DCqWLVz8GkaL
%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D
1272026745%26oauth_token%3Dabcdefghi%26oauth_version%3D1.0%26
xoauth_requestor_id%3D0123456

※ 上記Base Stringは、HTTPリクエストメソッドがGETで、http://os.gree.net/api/rest/people/@me/@selfにアクセスを行う場合の生成例です。

※ 生成データに改行は含まれません。

4.2.2. OAuth Signatureの生成

4.2.1.で生成したBase Stringをもとに、OAuth Signatureを生成します。

手順1. OAuth Signature生成用キーの生成

Consumer Secretとoauth_token_secretを'&'で連結し、OAuth Signature生成用のキーを作成します。

生成例

生成データ d522g1ab4ke93kdie748g719g07a781c&jklmnopqrstu
手順2. OAuth Signatureの生成

Base Stringに対して、手順1.で生成したキーを用いてHMAC-SHA1アルゴリズムでハッシュ値を生成し、結果をBASE64エンコードします。

生成例

キー d522g1ab4ke93kdie748g719g07a781c&jklmnopqrstu
生成元データ(Base String) GET&http%3A%2F%2Fos.gree.net%2Fapi%2Frest%2Fpeople
%2F%40me%2F%40self&key1%3Dvalue1%26key2%3Dvalue2%26
oauth_consumer_key%3Dd308e3ccg59e%26oauth_nonce%3DCqWLVz8GkaL
%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D
1272026745%26oauth_token%3Dabcdefghi%26oauth_version%3D
1.0%26xoauth_requestor_id%3D0123456
生成データ McJbJB9kwTKOWSwVVf4FbWiCWNw=

※ ハッシュ値を計算する場合は、hash_hmac()関数(PHPの場合)を利用して生成します。

4.2.3. Authorizationヘッダの生成

以下のパラメータのキーと値をURLエンコードし、値を'"'で囲んだ後、キーと値を'='で連結し、すべてを','で連結します。

生成元データ oauth_version="1.0",
oauth_nonce="CqWLVz8GkaL",
oauth_timestamp="1272026745",
oauth_consumer_key="d308e3ccg59e",
oauth_token="abcdefghi",
oauth_signature="McJbJB9kwTKOWSwVVf4FbWiCWNw%3D",
oauth_signature_method="HMAC-SHA1",
xoauth_requestor_id="0123456"

"Authorization: OAuth "を先頭に付加し、上記パラメータを一列に並べてAuthorizationヘッダを生成します。

生成例

生成データ Authorization: OAuth oauth_version="1.0",oauth_nonce=
"CqWLVz8GkaL",oauth_timestamp="1272026745",oauth_consumer_key=
"d308e3ccg59e",oauth_token="abcdefghi",oauth_signature="McJbJB9kwTKOWSw
VVf4FbWiCWNw%3D",oauth_signature_method="HMAC-SHA1",
xoauth_requestor_id="0123456"

※ 生成データに改行は含まれません。

4.2.4. HTTPヘッダへの追加と送信

生成したAuthorizationヘッダを、APIサーバーへのHTTPリクエストに追加して送信します。

4.3. OAuthパラメータの生成と送信方法(バッチタイプ利用時)

APIサーバーへのリクエスト送信時に必要なAuthorizationヘッダを生成し、HTTPリクエスト内のヘッダー部に"Authorization"ヘッダとして付加します。基本的な作業の流れはリクエストタイプと同じですが、生成に利用するOAuthパラメータが異なります。

手順は以下のとおりです。

4.3.1. Base Stringの生成

手順1. パラメータのソート

HTTPクエリパラメータとOAuthパラメータを合わせて、キーでアルファベット昇順に並べます。

HTTPクエリパラメータ

GETの場合 'http://HOST/?key1=value1&key2=value2' のうち 'key1=value1&key2=value2' の部分
POSTの場合 BODY部に記載される 'key1=value1&key2=value2' の部分

利用するOAuthパラメータ

パラメータ名サンプル値
oauth_consumer_key d308e3ccg59e
oauth_nonce CqWLVz8GkaL
oauth_timestamp 1272026745
oauth_signature_method HMAC-SHA1
oauth_version 1.0
手順2. パラメータの連結

すべてのキーと値を'='で連結し、各ペアを'&'で連結します。

生成例

生成データ key1=value1&key2=value2&oauth_consumer_key=d308e3ccg59e&oauth_nonce=CqWLVz8GkaL&
oauth_signature_method=HMAC-SHA1&oauth_timestamp=1272026745&oauth_version=1.0

※ 生成データに改行は含まれません。

手順3. Base Stringの生成

HTTPリクエストメソッド、アクセス先URL、手順2で生成した文字列のそれぞれをURLエンコードし、順に'&'で連結します。URLエンコード形式はRFC3986形式となります。結果、生成された文字列がBase Stringとなります。

生成例

生成データ POST&http%3A%2F%2Fos.gree.net%2Fapi%2Frest%2F messages%2F%40me%2F%40outbox&key1%3Dvalue1%26key2%3Dvalue2 %26oauth_consumer_key%3Dd308e3ccg59e%26oauth_nonce %3DCqWLVz8GkaL%26oauth_signature_method%3DHMAC-SHA1 %26oauth_timestamp%3D1272026745%26oauth_version%3D1.0

※ 上記Base Stringは、HTTPリクエストメソッドがPOSTで、http://os.gree.net/api/rest/messages/@me/@outboxにアクセスする場合の生成例です。

※ 生成データに改行は含まれません。

4.3.2. OAuth Signatureの生成

4.3.1.で生成したBase Stringをもとに、OAuth Signatureを生成します。

手順1. OAuth Signature生成用キーの生成

Consumer Secretの末尾に'&'を追加して、キーを生成します。

生成例

生成データ d522g1ab4ke93kdie748g719g07a781c&
手順2. OAuth Signatureの生成

Base Stringに対して、手順1.で生成したキーを用いてHMAC-SHA1アルゴリズムでハッシュ値を生成し、結果をBASE64エンコードします。

生成例

キー d522g1ab4ke93kdie748g719g07a781c&
生成元データ(Base String) POST&http%3A%2F%2Fos.gree.net%2Fapi%2Frest%2Fmessages %2F%40me%2F%40outbox&key1%3Dvalue1%26key2%3Dvalue2%26 oauth_consumer_key%3Dd308e3ccg59e%26oauth_nonce%3DCqWLVz8GkaL %26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1272026745%26oauth_version%3D1.0
生成データ M9ze2lZVQtihERXXXcdkcReG7e8=

※ ハッシュ値を計算する場合は、hash_hmac()関数(PHPの場合)を利用して生成します。

4.3.3. Authorizationヘッダの生成

以下のパラメータのキーと値をURLエンコードし、値を'"'で囲んだ後、キーと値を'='で連結し、すべてを','で連結します。

生成元データ oauth_version="1.0",
oauth_nonce="CqWLVz8GkaL",
oauth_timestamp="1272026745",
oauth_consumer_key="d308e3ccg59e",
oauth_signature="M9ze2lZVQtihERXXXcdkcReG7e8%3D",
oauth_signature_method="HMAC-SHA1"

"Authorization: OAuth "を先頭に付加し、上記パラメータを一列に並べてAuthorizationヘッダを生成します。

生成例

生成データ Authorization: OAuth oauth_version="1.0",oauth_nonce="CqWLVz8GkaL",
oauth_timestamp="1272026745",oauth_consumer_key="d308e3ccg59e",
oauth_signature_method="HMAC-SHA1",oauth_signature=
"M9ze2lZVQtihERXXXcdkcReG7e8%3D"

※ 生成データに改行は含まれません。

4.3.4. HTTPヘッダへの追加と送信

生成したAuthorizationヘッダを、APIサーバーへのHTTPリクエストに追加して送信します。

4.3.5. Message APIを利用するOAuth(Batch Type)のサンプルコード

※ このサンプルで利用されるOAuthライブラリ:http://code.google.com/p/oauth/

※ このサンプルで利用されるHTTP/Request2ライブラリ:http://pear.php.net/package/HTTP_Request2

<?php

require_once 'PATH/TO/OAUTH/OAuth.php';
// This code sample uses the HTTP/Request2 library.
require_once 'HTTP/Request2.php';
 
$app_conf = parse_ini_file('/PATH/TO/CONFIG/oauth_config', true);

// Contents of oauth_config file:
// # This config file stores the consumer key and consumer secret on the developer's game server.
// # Do not put this in a publicly accessible directory.
// 
// [oauth]
// consumer_key = XXXXXXXXXXXX
// consumer_secret = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// # this is the RESTFul endpoint for Sandbox games.
// # For production games, use http://os.gree.jp/api/rest
// api.endpoint_url = http://os-sb.gree.jp/api/rest

//
// 
$oauth_conf = $app_conf['oauth'];


// The Message API is a batch api, meaning it does not require a user's credentials, 
// so there is no need to add an access token to the Authentication header, 
// simplifying the authentication flow for batch APIs.
// Replace the number in the Recipients array with the id's of up to 20 players of your game.
// The title is limited to 26 bytes, the body is limited to 100 bytes.  
// The text will be truncated.
$user_message = <<<MESSAGE
   {
    "title":"Notification of fishing tournament",
    "body": "A fishing tournament will be held. Everyone is welcome to participate!",
    "recipients": [
      123456
    ],
    "urls": [
      {
        "value": "http://example.com/?action=message&a=1&b=2&c=3"
      }
    ],
    "attrs": [
      {
        "param1" : "value1",
        "param2" : "value2",
        "param3" : "value3"
      }
    ]
  }
MESSAGE;

$user_json_message = json_decode($user_message); 

// api endpoint
$endpoint_url = $oauth_conf['api.endpoint_url'] . '/messages/@me/@outbox';

$http_method = 'POST';
  
// sign request
$signature_method = new OAuthSignatureMethod_HMAC_SHA1();
$oauth_consumer = new OAuthConsumer($oauth_conf['consumer_key'], $oauth_conf['consumer_secret']);
$oauth_request = OAuthRequest::from_consumer_and_token(
    $oauth_consumer,  
    NULL, 
    $http_method, 
    $endpoint_url, 
    NULL 
);
$oauth_request->sign_request($signature_method, $oauth_consumer, NULL);
 
// get header
$authorization_header_string = $oauth_request->to_header();
$authorization_header = substr($authorization_header_string, strlen('Authorization:'));
 
// build api request
$http_options = array('timeout' => '10');
$http_request = new HTTP_Request2($endpoint_url, HTTP_Request2::METHOD_POST, $http_options);
$http_request->setHeader('Content-Type', "application/json");
$http_request->setHeader('Authorization', $authorization_header);
$http_request->setBody($user_message);

 
// send api request
$request_response = $http_request->send();
 
// get api result
$response_code = $request_response->getStatus();

header('HTTP/1.1 ' . $response_code);
echo $request_response->getBody();

5. 参考

OAuth 1.0(RFC5849)

http://tools.ietf.org/html/rfc5849

ホーム OAuth認証方法について