mixi Connect » mixi Graph API » 認証認可手順(新方式)
認証認可手順(新方式)
各種APIをクライアントプログラムから利用するためには、OAuth 2.0 Protocolにより規定された認可を行うことが求められます。この手順により、クライアントプログラムがどのようなAPIアクセスを行い、そしてどのような情報が参照または更新されるのか(これをスコープと呼びます)がユーザに提示されます。ユーザの認証、および提示されたスコープについてユーザが同意した場合にのみ、クライアントプログラムはAPIにアクセスするための情報(トークンなど)を得ることができます。
[RFC 6749 - The OAuth 2.0 Authorization Framework]
http://tools.ietf.org/html/rfc6749
[RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage]
http://tools.ietf.org/html/rfc6750
ここでは、APIを利用するために必要となる認証認可手順について説明いたします。
事前に必要なもの
認証認可手順を始めるためには、以下の情報をすでに入手している必要があります。
- Consumer key (サービス登録後に発行されたもの)
- Consumer secret (サービス登録後に発行されたもの)
これらを入手するためには、サービス管理のページをご覧ください。
server_stateの入手
mixi PlatformではCSRF対策として、server_stateを用いた拡張仕様を検討し、導入しています。次の「認可とAuthorization Codeの入手」の手順でscopeパラメータに"openid"を指定する場合はserver_stateの利用が必須となります。その他のscopeパラメータを指定する場合はserver_stateの利用は任意ですが、利用することを推奨します。
クライアントプログラムは、server_stateを入手します。そのために、クライアントプログラムは”https://secure.mixi-platform.com/2/token”にPOSTにてアクセスします。その際、以下のパラメータをリクエストボディにapplication/x-www-form-urlencoded形式で指定します。
パラメータ名 | 指定する値 |
---|---|
grant_type | “server_state” |
client_id | Consumer key |
全体のURLおよびリクエストボディは以下のようになるでしょう。
POST https://secure.mixi-platform.com/2/token
grant_type=server_state&client_id=908ed4da74f885a2ab
各パラメータが正しければ、レスポンスとして以下のような結果が返却されます。結果の形式は、application/jsonとなります。
{"server_state":"WErVieau7umEw1k2aRYOqXL-syCeRzZ3M4UBClLeZ2k","expires_in":1800}
それぞれの値の意味は、以下となります。
パラメータ名 | 意味 |
---|---|
server_state | 認可の要求とアクセストークンの入手時に指定するserver_state文字列 |
expires_in | server_stateが失効するまでの時間(秒) |
クライアントプログラムは、このserver_stateパラメータを現在のセッションに紐づけて管理します。
認可とAuthorization Codeの入手
最初にクライアントプログラムは、Webブラウザにて以下のURLにアクセスします。
- PC、スマートフォン向け: https://mixi.jp/connect_authorize.pl
- 携帯電話端末向け: http://m.mixi.jp/connect_authorize.pl
その際に指定しなければならないクエリーパラメータは以下となります。
パラメータ名 | 指定する値 |
---|---|
client_id | Consumer key |
response_type | “code” |
scope | 認可したいスコープ |
display | 認証認可画面を表示するデバイス |
state | ユーザの認可後に行われるリダイレクト時にこの値が含まれます。 アプリケーションがセッションを持つ場合、このパラメータを使用してセッションが維持されている事を確認してください。 |
server_state | 前の手順で取得したserver_stateパラメータを指定してください。 ユーザの認可後のリダイレクト時に含まれるAuthorization Codeにこの値が紐づけられます。 |
scopeパラメータ値は、認可したいスコープを空白区切りで列挙した文字列を指定します。指定可能なスコープは、各APIの説明ページを参照ください。
displayパラメータは、クライアントプログラムのデバイスによって指定する値を使い分けます。指定可能なパラメータ値は、以下となります。
指定可能な値 | 意味 |
---|---|
“pc” | PCデスクトップ向け画面が表示されます。 |
“touch” “smartphone” |
スマートフォン向け画面が表示されます。 |
“ios” | iOSの場合に指定します。Appleの審査を通過するために、このパラメータを使用してください。 |
利用デバイスが携帯電話端末だった場合は、displayパラメータの指定は無視され、携帯電話端末向け画面が表示されます。その際、Docomo携帯端末の場合は、クエリパラメータとして「guid=ON」を付与してください。
stateパラメータを利用したセッション維持の確認がされない場合、アプリケーションにCSRF脆弱性が存在する事になります。
これを防ぐために、セッションIDのハッシュ値等をstateパラメータに含めて下さい。そして、ユーザ認可後のリダイレクト時に、セッションとstateパラメータの組み合わせが正しいことを確認してください。
詳しくは下記URLをご参照ください。
http://openid-foundation-japan.github.io/rfc6749.ja.html#CSRF
server_stateパラメータを利用することにより、CSRF脆弱性を防ぐことができます。
ユーザ認可後のリダイレクト時に含まれるAuthorization Codeとserver_stateの値が紐づけられますが、server_stateの値は含まれません。クライアントプログラムはあらかじめ自らのセッションとserver_stateを紐づけておく必要があります。
全てのパラメータ値は、URLエンコード済みの文字列を指定します。全体のURLは以下のようになるでしょう。
GET https://mixi.jp/connect_authorize.pl?client_id=908ed4da74f885a2ab&response_type=code&scope=r_profile%20r_voice&state=5c1b3eea390b53f54ad0975e9a4bbba2
各パラメータ値が正しければ、Webブラウザ上には認証または認可画面が表示されます。認証画面は、ユーザがすでに”http://mixi.jp/”または”https://mixi.jp/”にて最近ログインを行っていた場合は表示されません。また、携帯電話端末の場合について、ユーザがかんたんログインを設定していない場合は、その旨の案内ページが表示されます。認可画面には、先ほどscopeパラメータで指定したスコープの一覧が表示され、ユーザはクライアントプログラムが表示された処理をすることに同意するか選択します。
ユーザが同意した場合は、サービス登録時に入力したRedirect URLにリダイレクトされます。その際、クエリパラメータとしてcodeパラメータが付与されます。このcodeパラメータ値が、mixi Platformにて発行されたAuthorization Codeとなります。また、stateパラメータを指定していた場合は、クエリパラメータとしてその値も含まれます。リダイレクト時のURLは、例えば以下のようになります。
http://example.com/callback?code=347ab1db9398d60b5ef3515e672d1e&state=5c1b3eea390b53f54ad0975e9a4bbba2
発行されたAuthorization Codeの有効期限は3分となります。
※この手順はmixi Graph APIサービスで「認可とAuthorization Codeの入手」を行うためのものです。mixiアプリからGraph APIを利用する際に「ユーザ認可とAuthorization Codeの入手」を行う場合は、そちらの各手順(PC、モバイル、スマートフォン)に従ってください。次項「リフレッシュトークン、アクセストークンの入手」以下の手順は、mixiアプリからの利用でも同様となります。
リフレッシュトークン、アクセストークンの入手
クライアントプログラムは、発行されたAuthorization Codeを利用して、リフレッシュトークンおよびアクセストークンを入手します。そのために、クライアントプログラムは”https://secure.mixi-platform.com/2/token”にPOSTにてアクセスします。その際、以下のパラメータをリクエストボディにapplication/x-www-form-urlencoded形式で指定します。
パラメータ名 | 指定する値 |
---|---|
grant_type | “authorization_code” |
client_id | Consumer key |
client_secret | Consumer secret |
code | Authorization Code |
server_state | ユーザ認可後のリダイレクトを受けたセッションに紐づけられた、server_stateの値 |
全体のURLおよびリクエストボディは以下のようになるでしょう。
POST https://secure.mixi-platform.com/2/token
grant_type=authorization_code&client_id=908ed4da74f885a2ab&client_secret=9720b4826e90ad9f053a57500d3a8c697c01d1&code=347ab1db9398d60b5ef3515e672d1e
各パラメータが正しければ、レスポンスとして以下のような結果が返却されます。結果の形式は、application/jsonとなります。
{"refresh_token":"39c5662a2e8b87d41c1eebe79f68af","expires_in":900,"access_token":"c2be2257f3dae3df4efcb010ae6eea","token_type":"Bearer","scope":"r_profile r_voice"}
それぞれの値の意味は、以下となります。
パラメータ名 | 意味 |
---|---|
refresh_token | アクセストークンを更新する際に利用するリフレッシュトークン文字列 |
expires_in | アクセストークンが失効するまでの時間(秒) |
access_token | アクセストークン文字列 |
token_type | アクセストークンの種類。"Bearer"という値が返されます。 |
scope | ユーザーが認可したスコープを半角スペース区切りで連結した文字列 |
id_token | 認可イベントの内容を含む文字列。 スコープに"openid"が含まれるときのみ、この値が含まれます。 |
id_tokenの詳細については、「ID Tokenについて」をご参照ください。
発行されたアクセストークンの有効期限は15分間となります。
リフレッシュトークンおよびアクセストークンの有効期間は、事前の予告なく変更する場合があります。そのため、これらの有効期間をクライアントプログラムにハードコーディングする、あるいはこれらの有効期間に基づく設計を行うことは避けるようお願いいたします。
もし、リクエストボディに指定したパラメータが不正であれば、リフレッシュトークンおよびアクセストークンは取得できません。その際、application/json形式のエラーメッセージが返されます。エラー内容は下記の通りです。
エラー内容 | 意味 |
---|---|
{"error":"invalid_grant"} | code値が不正である |
{"error":"invalid_client"} | client_idまたはclient_secret値が不正である |
{"error":"unsupported_grant_type"} | grant_type値が不正である |
APIへのアクセス
入手したアクセストークンを使用して、各種APIにアクセスすることができます。利用可能なAPIは、認可手順の際に指定したスコープに限定されます。
各APIを利用するためのURIはそれぞれ異なりますが、アクセストークンの指定は共通です。各種APIを呼び出す際に、 Authorizationリクエストヘッダにアクセストークンを指定します。例えば、以下のようになるでしょう。”Bearer”という文字列に続けて1 空白入れた後にアクセストークンを記述します。
GET /resource HTTP/1.1 Host: api.mixi-platform.com Authorization: Bearer c2be2257f3dae3df4efcb010ae6eea
もしAuthorizationリクエストヘッダが使用できない状況の場合は、access_tokenパラメータにアクセストークンを指定することも可能です。例えば、People APIを利用する場合には、以下のようになるでしょう。
https://api.mixi-platform.com/2/people/@me/@self?access_token=c2be2257f3dae3df4efcb010ae6eea
通常はAuthorizationリクエストヘッダにてアクセストークンを指定するようにしてください。
APIアクセス時のエラーについて
APIへのアクセスの際に使用したアクセストークンが以下のような理由により無効だった場合、APIの呼び出しは失敗し、エラー内容がレスポンスとして返却されます。
- アクセストークンの有効期限切れ
- 必要なスコープが認可されていない
この場合、HTTPレスポンスヘッダにエラー内容を示す”WWW-Authenticate”ヘッダが含まれます。
HTTP/1.1 401 Authorization Required ... WWW-Authenticate: Bearer error="invalid_token", error_description="The access token expired"
errorの値としては、以下の種類があります。
invalid_request | 不正なリクエスト内容 |
---|---|
invalid_token | 不正なアクセストークン |
insufficient_scope | アクセスに必要なスコープが認可されていない |
アクセストークンが有効期限切れの場合はerror_descriptionに"The access token expired"という値が入ります。「アクセストークンの再発行」を参考に再発行リクエストを発行してください。それ以外の不正なアクセストークン (invalid_token) の場合は「認可とAuthorization Codeの入手」からやり直してください。
アクセストークンの再発行
発行されたアクセストークンの有効期限は短く、その有効期限を越えたアクセストークンを使用しても各APIへのアクセスは失敗します。クライアントプログラムは、リフレッシュトークンを使って、アクセストークンの再発行を行うことが可能です。リフレッシュトークンは、アクセストークンの発行時に含まれるrefresh_token値となります。
アクセストークンの再発行を行うために、クライアントプログラムは”https://secure.mixi-platform.com/2/token”にPOSTにてアクセスします(先ほどのアクセストークン発行時と同じです)。その際、以下のパラメータをリクエストボディにapplication/x-www-form-urlencoded形式で指定します。
パラメータ名 | 指定する値 |
---|---|
grant_type | “refresh_token” |
client_id | Consumer key |
client_secret | Consumer Secret |
refresh_token | リフレッシュトークン文字列 |
全体のURLおよびリクエストボディは以下のようになるでしょう。
POST https://secure.mixi-platform.com/2/token
grant_type=refresh_token&client_id=908ed4da74f885a2ab&client_secret=9720b4826e90ad9f053a57500d3a8c697c01d1&refresh_token=39c5662a2e8b87d41c1eebe79f68af
各パラメータの値が正しければ、以下のような結果を得るでしょう。
{"refresh_token":"39c5662a2e8b87d41c1eebe79f68af","expires_in":900,"access_token":"b1bdf0cd88d4b400dfe785da132a9a","token_type":"Bearer","scope":"r_profile r_voice"}
access_token値として、新しく発行されたアクセストークンを得ることができます。この新しいアクセストークンを使用して、各種APIの利用を継続することが可能です。
リフレッシュトークンの期限切れ
リフレッシュトークンは、ユーザの認可状況あるいはAPIの利用状況によって、有効期限が切れることがあります。リフレッシュトークンの有効期限が切れていた場合にアクセストークンの再発行を試みた場合は、以下のようなレスポンスが返却されます。
HTTP/1.1 401 Authorization Required Content-Type: application/json ... {"error":"invalid_grant"}
期限の切れたリフレッシュトークンは一切使えませんので、改めて「認可とAuthorization Codeの入手」からやり直し、新しいトークンを取得するようにしてください。
ID Tokenについて
スコープに"openid"の値を指定した場合、アクセストークンと一緒に認可処理に関する情報を表すID Tokenが入手できます。ID TokenはOpenID Connect Core 1.0という仕様で定義されています。詳細については下記URLをご参照ください。
http://openid.net/specs/openid-connect-core-1_0.html#IDToken
ID Tokenの文字列は次のようなJSON Web Tokenと呼ばれる形式となっています。
eyJraWQiOiIyMDEzMTEiLCJ0eXAiOiJKT1NFIiwiYWxnIjoiUlMyNTYifQ.eyJleHAiOjEzODMyOTA2MzUsInNlcnZlcl9zdGF0ZSI6IldFclZpZWF1N3VtRXcxazJhUllPcVhMLXN5Q2VSelozTTRVQkNsTGVaMmsiLCJzdWIiOiJxZ2p3ODd5ZzNkanciLCJpYXQiOjEzODMyODcwMzUsImF1ZCI6IjkwOGVkNGRhNzRmODg1YTJhYiIsImlzcyI6Imh0dHBzOi8vYXBpLm1peGktcGxhdGZvcm0uY29tIn0.uCkNoPV-5dl1FZva26vN2TvwzTLPMDcEN89LVm8uLFYU3v8MD3KwHba790RafUXm_5luLTugdKYXV45Rr9JjR1FjjG3ppbZMeOuDzmDMQTeaWZPdnNK6W1UUpeWNxbfHnsUPeMnOREUIq0bLAV4uolZ53ym6my7jZH2Xg1bYzolV0PGXyzR0Ztpv5xnkBxVmFRZ4sFrNv8UJTpkXYrBlzGii5_e9AY2Qn40fkTlhOOIoDjgFnk2Jt1AdFKUrKtkOTsRXfkMuhf7ll86ZgTqR2Y0Il92J9Ivtk3S-GYc4Gh7tP4BNczfjh_2BdlyXlbkzPy5sN_pfr2JkbOuH0oDB9Q
JSON Web Tokenについては下記URLをご参照ください。
http://openid-foundation-japan.github.io/draft-ietf-oauth-json-web-token-11.ja.html
http://openid-foundation-japan.github.io/draft-ietf-jose-json-web-signature-14.ja.html
ID Tokenはピリオド(.)で区切られた3つ文字列により構成されています。
最初の文字列をBase64 URLデコードすることで次のような署名に関する情報が取得できます。
{"kid":"201311","typ":"JOSE","alg":"RS256"}
パラメータ名 | 意味 |
---|---|
typ | JWSオブジェクトの種類を表す文字列。“JOSE”という値はJWS Compact Serializationを用いていることを表します。 |
kid | 署名生成に用いられた公開鍵を識別する文字列 |
alg | 署名生成に用いられたアルゴリズム。 “RS256”という値はハッシュアルゴリズムにSHA-256を用いてRSASSA-PKCS-v1_5アルゴリズムで署名を生成したことを表します。 |
2番目の文字列をBase64 URLデコードすることで次のような認可処理に関する情報が取得できます。
{ "exp":1383290635, "server_state":"WErVieau7umEw1k2aRYOqXL-syCeRzZ3M4UBClLeZ2k", "sub":"qgjw87yg3djw", "iat":1383287035, "aud":"908ed4da74f885a2ab", "iss":"https://api.mixi-platform.com", "openid2_id":"https://id.mixi.jp/user_id" }
パラメータ名 | 意味 |
---|---|
iss | ID Tokenの発行者を表す文字列。"https://api.mixi-platform.com"という値が指定されます。 |
aud | ID Tokenの発行対象を表す文字列。クライアントプログラムのConsumerKeyの値が指定されます。 |
sub | 認可を行ったユーザの識別子 |
iat | ID Tokenが発行された日時 |
exp | ID Tokenが無効になる日時 |
server_state | 認可処理に用いたserver_stateの値。この値はmixi Platform独自のパラメータとなります。 |
openid2_id | mixi OpenID で提供していたユーザID。この値はスコープに"openid"と"openid2"の値を指定した時に含まれます。 |
このsubパラメータの値を取得することで、People APIなどを利用しなくても認可を行ったユーザの識別子を取得できます。
3番目の文字列は署名となります。
この署名の検証を行うために必要なRSA公開鍵を含むX.509形式の証明書は下記のようになります(kid=“201311”)。
-----BEGIN CERTIFICATE----- MIIDNzCCAh+gAwIBAgIJAJjXIVKEYTpLMA0GCSqGSIb3DQEBBQUAMDIxCzAJBgNV BAYTAkpQMREwDwYDVQQKDAhtaXhpIEluYzEQMA4GA1UEAwwHbWl4aS5qcDAeFw0x MzExMTUwNjA1NDlaFw0yMzExMTMwNjA1NDlaMDIxCzAJBgNVBAYTAkpQMREwDwYD VQQKDAhtaXhpIEluYzEQMA4GA1UEAwwHbWl4aS5qcDCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBANhIUPkNC+lutt0/wWUUBB4F0Zwu5aLMHTdy9cz4Gc85 hmjKKwq7VdNo/ZLFZv1vtsR+kYymeMgNe2bAItPt99GLONsFx+v7DjwGYz2qTwdI 3HfiDyyUuW9nPEf7F0MthdlqmgSLVPhfU9uXOKIOKtK5QlRoPJTvIckr6CmSd90L 3dtfiOBFDEqUjJzZHomJ1L6Wt/Qv1vMV9YWkLzWjmtneWLkrfUAi5H8MVViDwRvh jmYhN1wG8wn7g3/CL7cOZ7AdhY25e82p9ZG3Q7xcr+GaxPEe3uNDKvBSka+F8TKV NezI3FLIauzR5n+dcWTe0AqYFDLqrzPaWfT21xPy54MCAwEAAaNQME4wHQYDVR0O BBYEFKpfIm0r4dOUjP4vUSmLqTnpyloxMB8GA1UdIwQYMBaAFKpfIm0r4dOUjP4v USmLqTnpyloxMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAJPT65qT 7isKxk+xmfkg5Hr2lPP0XesRFtdzt+2OIdFdenBF3viCLV5KF+4kV70dA02mDiUV eoVu0ykxTT91MmQwM4A18F0OuZgVDQ9XbFBbf/Awd08PW2+8de84+NGh7XyqTgn/ 0yTRCIYAKwg4oh/fE1FQhHDtdAtiPjZOlTdSmzHSWR4qcnAKyN7fshdtS1NSKflR YAhnU+4d1veR26MGrjwGR9g0GxOZthvi35Mzz/YnKrbzXDCQZubw7Qd+EU5Q40UV dtAKBpWVPzJBYt+iZGlYvlqQ9uMS950Eh8Ql74WW1qohHCq5Vo+yxSg+qlk6UYtf OrYAVnC1QJoxZb8= -----END CERTIFICATE-----
2023年11月13日以降は下記の証明書を使用してください。
-----BEGIN CERTIFICATE----- MIIDKDCCAhACCQCgQPbBHa3zlzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJK UDEOMAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB1NoaWJ1eWExEzARBgNVBAoMCk1J WEksIEluYy4xEDAOBgNVBAMMB21peGkuanAwHhcNMjMwOTEzMDQxNDQ0WhcNMjgx MjE1MDQxNDQ0WjBWMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xEDAOBgNV BAcMB1NoaWJ1eWExEzARBgNVBAoMCk1JWEksIEluYy4xEDAOBgNVBAMMB21peGku anAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYSFD5DQvpbrbdP8Fl FAQeBdGcLuWizB03cvXM+BnPOYZoyisKu1XTaP2SxWb9b7bEfpGMpnjIDXtmwCLT 7ffRizjbBcfr+w48BmM9qk8HSNx34g8slLlvZzxH+xdDLYXZapoEi1T4X1Pblzii DirSuUJUaDyU7yHJK+gpknfdC93bX4jgRQxKlIyc2R6JidS+lrf0L9bzFfWFpC81 o5rZ3li5K31AIuR/DFVYg8Eb4Y5mITdcBvMJ+4N/wi+3DmewHYWNuXvNqfWRt0O8 XK/hmsTxHt7jQyrwUpGvhfEylTXsyNxSyGrs0eZ/nXFk3tAKmBQy6q8z2ln09tcT 8ueDAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJGG+pcpj67MZBvTi/wADLAwUbPt e4KdVzyRF/cQvrH8yTlcdL8vWffpbNkKIrJ0t4WayYRd5gtIHPmd8AD/BPTihgo8 O826G9O2JtnCnUGt9g3PaekTY120dckqXv9XPNwJrcTjThP52fTIHdS4U2a4XKm3 ewDaeaNLU21OhNXhatKHQsayKT3AJKjaNd/X1i7ZnSvdrgRWmlNTUWZ7UbP3M1Bf oL/3hBMrgEd7Bp5h4g16ESdOdyXwvrMpr6M4hWmWdWRLbxGUVh5AhPVwbf5h8mLI FFiFMih7GJdLvOuG/M0KZduHRWyvG6jtQIch0xHOnUM/r/BEn1G4H9lsV+w= -----END CERTIFICATE-----
mixi Graph APIが採用しているAuthorization Codeを用いたフローでは、HTTPリクエストにより直接ID Tokenを取得するため、取得直後のID Token取得時の署名検証は不要です。
「いつ、誰が、どこに認可処理を行った」というデータに署名がついている文字列をWebサーバーとモバイルアプリ間の通信に含むことで、クライアントプログラムのユーザーやセッションの識別に活用できるでしょう。