ユーザープロファイル情報を取得する


ユーザープロファイル情報を取得する

AmazonユーザープロファイルへのアクセスをユーザーがTVやそのほかのデバイスに許可すると、アクセストークンが返されます。サーバー側のスクリプトで認可コードグラントを使用してアクセストークンをリクエストしている場合、アクセストークンはアクセストークンレスポンスで返されます。

インプリシットグラントを使用している場合は、認可レスポンスでURIフラグメントとして返されます。許可されたユーザーデータにアクセスするには、HTTPSを使用して、受け取ったアクセストークンをLogin with Amazonに送信します。

そのレスポンスとして、Login with Amazonは該当するユーザープロファイルデータを返します。ここで返されるプロファイルデータは、アクセスをリクエストする際にscopeで指定したスコープによって決まります。アクセストークンに従って、そのスコープにアクセスできるようになります。

サーバー側でprofileエンドポイントを呼び出す

profileエンドポイントを直接呼び出す場合、アクセストークンを指定する方法は、クエリパラメーターとして指定する、Bearerトークンとして指定する、HTTPヘッダーにx-amz-access-tokenを使用する、の3とおりあります。次に例を示します。

https://api.amazon.com/user/profile?access_token=AtzaIIQEBLjAsAhRmHjNgHpi0UDme37rR6CuUpSR...
GET /user/profile HTTP/l.l
Host: api.amazon.com
Date: Wed, 0l Jun 20ll l2:00:00 GMT
Authorization: Bearer Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...
GET /user/profile HTTP/l.l
Host: api.amazon.com
Date: Wed, 0l Jun 20ll l2:00:00 GMT
x-amz-access-token: Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...

Login with Amazonは、コンテンツタイプとしてapplication/jsonのみを、コンテンツ言語としてen-usのみをサポートします。明記されていない場合でも、Login with Amazonではこのコンテンツタイプと言語をデフォルトで使用します。

GET /user/profile HTTP/l.l
Host: api.amazon.com
Date: Wed, 0l Jun 20ll l2:00:00 GMT
x-amz-access-token: Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...
Accept: application/json
Accept-Language: en-US

以下の各言語の詳細なコードサンプルは次のようになります。

PHPのサンプル
サーバー側のアプリで、「handle_login.php」に対するリクエストを処理し、アクセストークンとプロファイルREST APIを使用してプロファイル情報を取得します。次のコードサンプルを使用する場合、「YOUR-CLIENT-ID」を上記の「アプリを登録する」セクションのクライアントIDに置き換えます。**注意**: このサンプルコードを使用するには、「pycurl」(http://pycurl.sourceforge.net/)ライブラリをダウンロードする必要があります。
    import pycurl
    import urllib
    import json
    import StringIO

    ...

    b = StringIO.StringIO()

    # アクセストークンがこちらに属していることを検証する
    c = pycurl.Curl()
    c.setopt(pycurl.URL, "https://api.amazon.com/auth/o2/tokeninfo?access_token=" + urllib.quote_plus(access_token))
    c.setopt(pycurl.SSL_VERIFYPEER, 1)
    c.setopt(pycurl.WRITEFUNCTION, b.write)

    c.perform()
    d = json.loads(b.getvalue())

    if d['aud'] != 'YOUR-CLIENT-ID' :
    # アクセストークンがこちらに属していない
    raise BaseException("Invalid Token")

    # アクセストークンをユーザープロファイルと交換する
    b = StringIO.StringIO()

    c = pycurl.Curl()
    c.setopt(pycurl.URL, "https://api.amazon.com/user/profile")
    c.setopt(pycurl.HTTPHEADER, ["Authorization: bearer " + access_token])
    c.setopt(pycurl.SSL_VERIFYPEER, 1)
    c.setopt(pycurl.WRITEFUNCTION, b.write)

    c.perform()
    d = json.loads(b.getvalue())

    print "%s %s %s"%(d['name'], d['email'], d['user_id'])
    
Rubyのサンプル
サーバー側のアプリで、「handle_login.php」に対するリクエストを処理し、アクセストークンとプロファイルREST APIを使用してプロファイル情報を取得します。次のコードサンプルを使用する場合、「YOUR-CLIENT-ID」を上記の「アプリを登録する」セクションのクライアントIDに置き換えます。
        require "rubygems"
        require "net/https"
        require "json"
        require "uri"

        ...

        # アクセストークンがこちらに属していることを検証する
        uri = URI.parse("https://api.amazon.com/auth/o2/tokeninfo?access_token=" + URI.encode(access_token))
        req = Net::HTTP::Get.new(uri.request_uri)
        http = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_PEER

        response = http.request(req)
        decode = JSON.parse(response.body)

        if decode['aud'] != 'YOUR-CLIENT-ID'
        # アクセストークンがこちらに属していない
        raise "Invalid token"
        end

        # アクセストークンをユーザープロファイルと交換する
        uri = URI.parse("https://api.amazon.com/user/profile")
        req = Net::HTTP::Get.new(uri.request_uri)
        req['Authorization'] = "bearer " + access_token
        http = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_PEER

        response = http.request(req)
        decode = JSON.parse(response.body)

        puts sprintf "%s %s %s", decode['name'], decode['email'], decode['user_id']
        
Javaのサンプル
サーバー側のアプリで、「handle_login.php」に対するリクエストを処理し、アクセストークンとプロファイルREST APIを使用してプロファイル情報を取得します。次のコードサンプルを使用する場合、「YOUR-CLIENT-ID」を上記の「アプリを登録する」セクションのクライアントIDに置き換えます。
        import com.fasterxml.jackson.core.type.TypeReference;
        import com.fasterxml.jackson.databind.ObjectMapper;
        import org.apache.http.client.fluent.Content;
        import org.apache.http.client.fluent.Request;

        import java.net.URLEncoder;
        import java.util.Map;

        ...

        // アクセストークンがこちらに属していることを検証する
        Content c = Request.Get("https://api.amazon.com/auth/o2/tokeninfo?access_token=" + URLEncoder.encode(access_token, "UTF-8"))
                       .execute()
                       .returnContent();

        Map m = new ObjectMapper().readValue(c.toString(), new TypeReference>(){});

        if (!"YOUR-CLIENT-ID".equals(m.get("aud"))) {
        // アクセストークンがこちらに属していない
        throw new RuntimeException("Invalid token");
        }

        // アクセストークンをユーザープロファイルと交換する
        c = Request.Get("https://api.amazon.com/user/profile")
               .addHeader("Authorization", "bearer " + access_token)
               .execute()
               .returnContent();

        m = new ObjectMapper().readValue(c.toString(), new TypeReference>(){});

        System.out.println(String.format("%s %s %s", m.get("name"), m.get("email"), m.get("user_id")));
        
Pythonのサンプル
サーバー側のアプリで、「handle_login.php」に対するリクエストを処理し、アクセストークンとプロファイルREST APIを使用してプロファイル情報を取得します。次のコードサンプルを使用する場合、「YOUR-CLIENT-ID」を上記の「アプリを登録する」セクションのクライアントIDに置き換えます。
        import pycurl
        import urllib
        import json
        import StringIO

        ...

        b = StringIO.StringIO()

        # アクセストークンがこちらに属していることを検証する
        c = pycurl.Curl()
        c.setopt(pycurl.URL, "https://api.amazon.com/auth/o2/tokeninfo?access_token=" + urllib.quote_plus(access_token))
        c.setopt(pycurl.SSL_VERIFYPEER, 1)
        c.setopt(pycurl.WRITEFUNCTION, b.write)

        c.perform()
        d = json.loads(b.getvalue())

        if d['aud'] != 'YOUR-CLIENT-ID' :
        # アクセストークンがこちらに属していない
        raise BaseException("Invalid Token")

        # アクセストークンをユーザープロファイルと交換する
        b = StringIO.StringIO()

        c = pycurl.Curl()
        c.setopt(pycurl.URL, "https://api.amazon.com/user/profile")
        c.setopt(pycurl.HTTPHEADER, ["Authorization: bearer " + access_token])
        c.setopt(pycurl.SSL_VERIFYPEER, 1)
        c.setopt(pycurl.WRITEFUNCTION, b.write)

        c.perform()
        d = json.loads(b.getvalue())

        print "%s %s %s"%(d['name'], d['email'], d['user_id'])
        

ユーザープロファイルのレスポンス

アクセストークンが有効な場合、ユーザーのプロファイルデータはJSON形式のHTTPレスポンスとして返されます。次に例を示します。

HTTP/l.l 200 OK
 x-amzn-RequestId: 0f6bef6d-705c-lle2-aacb-93e6bf26930l
 Content-Type: application/json
 Content-Language: en-US
 Content-Length: 85
 {
    "user_id": "amznl.account.K2LI23KL2LK2",
    "email":"mhashimoto-04@plaxo.com",
    "name" :"Mork Hashimoto",
    "postal_code": "98052"
 }

Request-Idはログ用であり、無視して構いません。Login with Amazonチームと問題のトラブルシューティングを行う場合、Request-Idの提供をAmazonチームに求められることがあります。

プロファイルリクエストの処理中に問題が発生すると、HTTPエラーが返されます。アクセスリクエストのエラーコードには、次のものがあります。

ステータス エラーコード 説明
200 成功 リクエストに成功しました。
400 invalid_request リクエストに必須パラメーターが含まれていないか、形式に誤りがあります。
400 invalid_token 提供されたアクセストークンは、期限切れ、取り消し済み、形式の誤り、またはそのほかの理由により無効です。
401 insufficient_scope 提供されたアクセストークンでは、必要なスコープにアクセスできません。
500 ServerError サーバーでランタイムエラーが発生しました。

エラーコードに加えて、詳しい情報を含むJSONペイロードが返されることもあります。次に例を示します。

HTTP/l.l 400 Bad Request
Content-Type: application/json;charset=UTF-8
Content-Length: 74
{
"error": "machine-readable error code",
"error_description": "human-readable error description",
"request_id": "bef0c2f8-e292-4l96-8c95-8833fbd559df"
}

サーバーにユーザー情報を取り込む

Amazonから取得したユーザープロファイル情報をバックエンドサーバーに取り込むことで、サインインしたユーザーを特定したり、ユーザーのアカウントをさらにカスタマイズしたりできます。これを安全に行うため、HTTPSを使用してクライアントからサーバーにアクセストークンを送信します。次にサーバー側からそのアクセストークンを使用して、profileエンドポイントを呼び出します。詳細と各種言語のコードサンプルについては、サーバー側でprofileエンドポイントを呼び出すを参照してください。Login with Amazonからは、user_idemailnamepostal_codeなどの値を含んだユーザープロファイルレスポンスが返されるので、それをサーバーに保存できます。

この手順を踏むことで、サーバーに保存したプロファイルデータを、クライアントにサインインしているユーザーに確実に対応付けることができます。バックエンドにおけるユーザーアカウントの結合と管理の詳細については、既存のアカウントシステムと統合するを参照してください。