授权码授予

授权码授予

授权码授予允许客户端(通常为网站)将用户代理(用户浏览器)定向至亚马逊的URI。然后,页面会请求用户授予访问其个人资料的网站权限。请求获得批准后,客户端将收到授权码,可通过此代码换取访问令牌刷新令牌

客户端获取访问令牌后可读取客户个人资料。如需了解更多有关客户体验的详细信息,请参阅授权授予

如果用户拒绝请求,客户端将收到发出的错误信息。授权服务

授权请求

要请求授权,客户端(网站)必须重定向用户代理(浏览器),使用以下参数对https://www.amazon.com/ap/oa作出安全的HTTP调用。如果您使用授权标头来请求访问令牌,则注意其客户端:客户端密钥应为base-64编码。

参数 描述
client_id 必需。客户端标识符。客户端标识符会在网站注册为Login with Amazon客户端时提供给您。最大不超过100字节。
scope 必需。请求范围。必须是profileprofile:user_idpostal_code或组合信息,并以空格分隔(如profile%20postal_code)。有关更多信息,请参阅客户个人资料
response_type 必需。请求的响应类型。此场景中必须为code
redirect_uri 必需。授权服务重定向用户的HTTPS地址。
state 推荐。客户端在请求和响应期间用来保持状态的不透明值。用户重定向返回客户端时,授权服务会将此值包括在内。此外,状态值还可用于阻止跨站点伪造请求。有关更多信息,请参阅跨站点伪造请求
code_challenge 推荐。通过代码交换证明密钥(PKCE)来确保授权码授予安全。基于浏览器的应用必须使用代码挑战,推荐将其用于所有应用类型。有关更多信息,请参阅PKCE RFC
code_challenge_method 推荐。用于为code_challenge参数编码code_verifier的方法。建议为S256。也可以设置为plain。如果不存在其他选项,则默认为plain

例如:

https://www.amazon.com/ap/oa?client_id=foodev
&scope=profile
&response_type=code
&state=208257577ll0975l93l2l59l895857093449424
&redirect_uri=https://client.example.com/auth_popup/token
&code_challenge=Fw7s3XHRVb2m1nT7s646UrYiYLMJ54as0ZIU_injyqw
&code_challenge_method=S256

要使用适用于JavaScript的Login with Amazon SDK提出授权请求,您必须填写options对象并调用amazon.Login.authorize

选项1: 服务器应用

适用于使用服务器端脚本的应用。此为建议集成方式。这种集成方式的令牌永远不会暴露给用户,因此更安全。访问令牌和刷新令牌都会进行返回。刷新令牌无需用户参与便可获取新的访问令牌。

options = { } ;
options.scope = 'profile';
options.response_type='code';
amazon.Login.authorize(options, function(response) {
  if ( response.error ) {
   alert('oauth error ' + response.error);
   return;
  }
  <!-- Pass response.code to your server, and use it to request refresh and
  access token. -->
});

选项2: 基于浏览器的应用

适用于无服务器支持的JavaScript应用。由于浏览器无法安全存储client_secret,必须使用PKCE (options.pkce = true)。访问令牌请求由用户浏览器作出,因此用户将暴露给访问令牌。从严格的安全角度来看,用户信息最好处于隐藏状态。因此将不会返回刷新令牌。访问令牌过期后,用户必须重新进行验证才能继续访问资源。如果您的架构支持服务器端脚本,我们建议在服务器上执行代码以交换令牌(选项1)。

options = { } ;
options.scope = 'profile';
options.pkce = true; // SDK生成`code_verifier`和`code_challenge`
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;
    }
    alert('Access Token: ' + response.access_token);
  });
});

amazon.Login.authorize的第一个参数始终为options对象。第二个参数为处理授权响应的JavaScript函数或重定向到另一界面的URI。URI必须与调用SDK的页面属于同一域,且必须使用HTTPS进行指定。

例如:

options = {} ;
options.scope = 'profile';
options.response_type = 'code';
amazon.Login.authorize(options, 'https://mysite.com/redirect_here');

用户请求已批准或拒绝后,授权服务器会将用户重定向到redirect_uri。客户端将收到授权响应(如下所述)。

授权响应

客户端(网站)指导用户代理(浏览器)作出授权请求后,授权服务会将用户代理重定向到客户端指定的URI。如果用户已对访问请求进行授权,则该URI将包含一个含有授权码code参数,以及含有+用户同意范围单独列表的scope参数。例如:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBezQQYbYS6WxSbIA
&state=208257577ll0975l93l2l59l895857093449424
&scope=profile

授权码的大小为18到128个字符。授权码有效期为5分钟。

重定向也会复制用户代理在授权请求中传递的state。您可以通过状态值跟踪用户请求前的状态。此外,状态还可用于阻止跨站点伪造请求

如果您使用适用于JavaScript的Login with Amazon SDK,以上参数可在amazon.Login.authorize提供的response对象中获取(示例参见上文授权请求部分)。

授权错误

如果用户未授予访问请求,或者出现错误,授权服务会将用户代理(用户浏览器)重定向到客户端指定的URI。该URI将包含具体的错误参数。例如:

HTTP/1.1 302 Found
Location: https://client.example.com/cb#error=access_denied
&state=208257577ll0975l93l2l59l895857093449424

授权请求失败的错误参数包括:

参数错误 描述
error 包含错误代码值的ASCII错误代码。
error_description 人类可读的ASCII字符串,含有错误相关信息,对客户端开发者非常有用。
error_uri 人类可读的网页URI,含有错误相关信息,对客户端开发者非常有用。
state 客户端在初始授权请求中传递的state

如果您使用适用于JavaScript的Login with Amazon SDK,以上参数可在amazon.Login.authorize提供的response对象中获取(示例参见上文授权请求部分)。

返回的error值中可能包含以下错误代码:

错误代码 描述
invalid_request 请求中缺少必要参数、具有无效值,或格式不正确。
unauthorized_client 客户端未获得请求授权码授予的授权。
access_denied 资源所有者或授权服务器拒绝了该请求。
unsupported_response_type 该请求指定了不受支持的响应类型。在此情景下,response_type必须为code
invalid_scope 客户端请求范围错误。
server_error 授权服务器发生意外错误(将其视为500内部服务器HTTP错误)。
temporarily_unavailable 授权服务器因暂时过载或计划维护而导致当前不可用(将其视为503服务不可用HTTP错误)。

访问令牌请求

客户端(网站)收到包含有效授权码的授权响应后,可使用该授权码获取访问令牌。有了访问令牌,客户端就可以读取客户个人资料。

为请求获取访问令牌,客户端会向以下区域终端节点之一发出安全HTTP POST请求:

  • 北美洲(NA) - https://api.amazon.com/auth/o2/token
  • 欧盟(EU) - https://api.amazon.co.uk/auth/o2/token
  • 远东(FE) - https://api.amazon.co.jp/auth/o2/token

请在POST请求中使用下表列出的参数。

参数 描述
grant_type 必需。请求的授权访问类型。必须为Authorization_code
code 必需。授权请求返回的代码。
redirect_uri 必需。如果您在授权请求中提供了redirect_uri,则在此情景下必须传递相同的redirect_uri。如果您使用适用于JavaScript的Login with Amazon SDK来提出授权请求,则在此情况下无需传递redirect_uri。 
client_id 必需。客户端标识符。客户端标识符在网站注册为客户端时进行设置。有关更多信息,请参阅客户端标识符
client_secret 可选。注册过程中分配给客户端的密钥值。由于网页无法安全存储客户端密钥,您不应在基于浏览器的应用中使用客户端密钥。在没有传递任何client_secret的情景下,将不会返回刷新令牌。如果code_verifier有效,则仍将返回访问令牌。
code_verifier 推荐。在授权请求中用于生成code_challenge的同一code_verifier。如果授权请求使用了code_challenge,则必须使用代码验证器。有关更多信息,请参阅PKCE RFC

例如:

POST /auth/o2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=authorization_code
&code=SplxlOBezQQYbYS6WxSbIA
&client_id=foodev
&client_secret=Y76SDl2F
&code_verifier=5CFCAiZC0g0OA-jmBmmjTBZiyPCQsnq_2q5k9fD-aAY

例如:

POST /auth/o2/token HTTP/1.1
Host: api.amazon.com
Authorization: Basic czzCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=authorization_code
&code=SplxlOBezQQYbYS6WxSbIA

要使用适用于JavaScript的Login with Amazon SDK来提出令牌请求,您必须在授权调用的options对象中将pkce设置为true。然后,使用在授权响应中从Authorize API返回的授权码调用amazon.Login.retrieveToken API。

在pkce设置为true、code_challenge未指定的情况下,SDK将生成code_verifiercode_challenge代码挑战将用于授权请求。code_verifier存储在amazon_Login_pkce_params Cookie中,并且会在令牌请求中被retrieveToken API用来获取访问令牌。

必须启用Cookie,且retrieveToken调用必须与authorize调用位于相同的域。有关更多信息,请参阅retrieveToken API

options = {}
options.scope = 'profile';
options.pkce = true;
amazon.Login.authorize(options, function(response) {
    amazon.Login.retrieveToken(response.code, callback);
    });

访问令牌响应

客户端(网站)作出安全的HTTP POST授权请求后,授权服务器将立即返回访问令牌,否则将返回HTTP响应错误。例如:

HTTP/1.1 200 OK
 Content-Type: application/json;charset UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 {
    "access_token":"Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...",
    "token_type":"bearer",
    "expires_in":3600,
    "refresh_token":"Atzr|IQEBLzAtAhRPpMJxdwVz2Nn6f2y-tpJX2DeX..."
}

成功的响应包括以下值:

参数 描述
access_token 用户账户的访问令牌。最大不超过2048字节。
token_type 返回的令牌类型。应为bearer
expires_in 访问令牌的有效秒数。
refresh_token 刷新令牌,可用于获取新的访问令牌。最大不超过2048字节。

响应参数使用application/json媒体类型进行编码。有关更多信息,请参阅RFC4627

访问令牌错误

对于某些错误,授权服务可能会返回HTTP 401(未授权)状态代码。这包括以下情况:客户端在授权标头中传递了client_idclient_secret值,但无法对客户端进行身份验证。

不成功的响应包括以下值:

错误参数 描述
error  包含错误代码值的ASCII错误代码。
error_description 人类可读的ASCII字符串,含有错误相关信息,对客户端开发者非常有用。
error_uri 人类可读的网页URI,含有错误相关信息,对客户端开发者非常有用。

返回的error值中可能包含以下错误代码:

错误代码 描述
invalid_request 请求中缺少必要参数、具有无效值,或格式不正确。
invalid_client 客户端身份验证失败。用于授权服务未返回HTTP 401(未授权)状态代码得情况。
invalid_grant 授权码无效、已过期、已撤销或已发放至另一client_id
unauthorized_client 客户端未获得使用授权码的授权。可能因code_verifier无效而导致。
unsupported_grant_type 客户端指定了错误的token_type
ServerError 服务器运行错误。

使用刷新令牌

访问令牌在设定时间过后将失效(通常将返回expires_in参数)。获取访问令牌后还会收到一个刷新令牌。您可以使用刷新令牌来检索新的访问令牌。

要提交刷新令牌,客户端将向https://api.amazon.com/auth/o2/token作出安全的HTTP POST,其中包含以下参数:

参数 描述
grant_type 必需。请求的授权访问类型。必须为refresh_token
refresh_token 必需。由初始访问令牌响应(见上文)返回的刷新令牌。

例如:

POST /auth/o2/token HTTP/1.1
Host: api.amazon.com
Authorization: Basic czzCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=refresh_token
&refresh_token=Atzr|IQEBLzAtAhRPpMJxdwVz2Nn6f2y-tpJX2DeX...

例如:

POST /auth/o2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=refresh_token
&refresh_token=Atzr|IQEBLzAtAhRPpMJxdwVz2Nn6f2y-tpJX2DeX...
&client_id=foodev
&client_secret=Y76SDl2F

提交刷新令牌的响应属于访问令牌响应