获取客户个人资料信息


获取客户个人资料信息

用户授权您的网站访问其亚马逊客户个人资料之后,您将收到一个访问令牌。如果您使用服务器端脚本,通过授权码授予来请求访问令牌,则访问令牌将在访问令牌响应中返回。

如果您使用基于浏览器的应用,并需要客户端的访问令牌,则可设置options.pkce = true并使用授权码调用retrieveToken API来获取访问令牌。为使API正常工作,客户端需要启用Cookie,且authorize调用必须与retrieveToken位于同一域中。要访问已授权的客户数据,您需要使用HTTPS将访问令牌提交给Login with Amazon。

Login with Amazon将在响应中返回相应的客户个人资料数据。您接收的个人资料数据取决于请求时指定的访问范围。访问令牌反映了访问权限范围。

使用适用于JavaScript的Login with Amazon SDK

如果您正在使用适用于JavaScript的Login with Amazon SDK,请使用amazon.Login.retrieveProfile将访问令牌换为个人资料。例如:

<script type="text/javascript">
    document.getElementById('LoginWithAmazon').onclick = function() {
       setTimeout(window.doLogin, l);
       return false;
    };
    window.doLogin = function() {
        options = {};
        options.scope = 'profile';
        options.pkce = true;
        amazon.Login.authorize(options, function(response) {
            if ( response.error ) {
                alert('oauth error ' + response.error);
            return;
            }
            amazon.Login.retrieveToken(response.code, function(response) {
                if ( response.error ) {
                    alert('oauth error ' + response.error);
                return;
                }
                amazon.Login.retrieveProfile(response.access_token, function(response) {
                    alert('Hello, ' + response.profile.Name);
                    alert('Your e-mail address is ' + response.profile.PrimaryEmail);
                    alert('Your unique ID is ' + response.profile.CustomerId);
                    if ( window.console && window.console.log )
                       window.console.log(response);
                });
            });
        });
   };
 </script>

amazon.Login.retrieveProfile函数将返回三个参数:successerrorprofilesuccess参数将说明此调用是否成功。如果发生错误,则error参数会包含错误信息。如果没有发生错误,profile参数将包含用户的个人资料。如需了解有关此方法及其参数的更多信息,请参阅适用于JavaScript的Login with Amazon SDK参考

调用服务器终端节点的个人资料

如果直接调用profile终端节点,您可以将访问令牌指定为以下三种方式中的任意一种:查询参数、不记名令牌或在HTTP标头使用x-amz-access-token。例如:

https://api.amazon.com/user/profile?access_token=AtzaIIQEBLjAsAhRmHjNgHpi0UDme37rR6CuUpSR...
GET /user/profile HTTP/1.1
Host: api.amazon.com
Date: Wed, 0l Jun 20ll l2:00:00 GMT
Authorization: Bearer Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...
GET /user/profile HTTP/1.1
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/1.1
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。

// 验证访问令牌属于我们
$c = curl_init('https://api.amazon.com/auth/o2/tokeninfo?access_token=' . urlencode($_REQUEST['access_token']));
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);

$r = curl_exec($c);
curl_close($c);
$d = json_decode($r);

if ($d->aud != 'YOUR-CLIENT-ID') {
  // 访问令牌不属于我们
  header('HTTP/1.1 404 Not Found');
  echo 'Page not found';
  exit;
}

// 使用访问令牌交换用户个人资料
$c = curl_init('https://api.amazon.com/user/profile');
curl_setopt($c, CURLOPT_HTTPHEADER, array('Authorization: bearer ' . $_REQUEST['access_token']));
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);

$r = curl_exec($c);
curl_close($c);
$d = json_decode($r);

echo sprintf('%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  =  StringIOStringIO  ()

# 验证访问令牌属于我们
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'])

客户个人资料响应

如果您的访问令牌有效,您将在HTTP响应中收到JSON形式的客户个人资料数据。例如:

HTTP/1.1 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

如果在履行个人资料请求过程中出现问题,您将收到HTTP错误代码。访问请求错误代码详情如下:

状态 错误代码 描述
200 Success 请求成功。
400 invalid_request 请求缺少必要参数或格式错误。
400 invalid_token 访问令牌已失效、已撤销、格式错误或因其他原因无效。
401 insufficient_scope 提供的访问令牌无权访问请求范围。
500 ServerError 服务器运行错误。

除错误代码以外,您还可能会收到包含更多信息的JSON有效负载。例如:

HTTP/1.1 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"
}

为您的服务器获取客户信息

您可以通过后端服务器从亚马逊获取客户个人资料信息,从而识别在您的服务器进行登录的用户,或者为用户创建更加个性化的账户。为安全地执行该操作,需要使用HTTPS将访问令牌从您的客户端发送到服务器。然后,在服务器端使用访问令牌调用profile终端节点。请参阅Call the profile endpoint server-side(调用服务器端的个人资料终端节点),了解详细信息和多语言代码示例。Login with Amazon返回的客户个人资料响应中包含多种值(如user_idemailname和/或postal_code),您可以将其保留在服务器中。

此步骤将确保您保存到服务器的个人资料数据属于登录到您客户端的客户。请参阅指南中的与您的现有账户系统集成部分,了解更多有关后端合并和管理用户账户的信息。