Taobao ID:淘宝OAuth2.0服务
原文http://open.taobao.com/doc2/detail.htm?articleId=118&docType=1&treeId=null
前言
如果您的应用和淘宝开放平台对接后,需要获取用户隐私信息(如:商品、订单、收藏夹等),为保证用户数据的安全性与隐私性,您的应用需要取得用户的授权。在这种情况下,您的应用需要引导用户完成“使用淘宝帐号登录并授权”的流程。
淘宝的Taobao ID(淘帐号)产品,采用国际通用的OAuth2.0标准协议,作为用户身份验证与授权协议,支持网站、手机客户端、桌面客户端。若要了解更多关于 OAuth2.0 的技术说明文档,可参看官方网站(http://oauth.net/2/) 。目前淘宝OAuth2.0服务支持采用以下4种获取Access Token(授权令牌)的方式:
- Server-side flow 此流程要求ISV应用有Web Server应用,能够保存应用本身的密钥以及状态,可以通过https直接访问淘宝的授权服务器。
- Client-side flow 此流程适用于没有独立服务器的应用,但是能够借助浏览器或者JS脚本访问授权服务器。
- Native Application 此流程适合客户端应用,同时应用无法与浏览器交互,但是可以外调用浏览器。
- Refreshing an Access Token 用户如果在获取访问令牌时,同时获取到了刷新令牌,当访问令牌过期时,用户可以用刷新令牌刷新,从而延长访问令牌的时间。
Taobao ID(淘帐号)产品不得用于阿里巴巴集团非官方渠道为淘宝买家提供淘宝会员类服务(如:订单查询、物流追踪 等),一旦发现违规使用,开放平台将立即收回该appkey的Taobao ID使用权限。
名词解释
1. redirect_uri及callback定义规则
2. View参数为以下可选值:
3.Access Token
Access Token即用户授权后颁发的session key
Server-side flow
1. 参数说明
1.1 获取授权码参数
参数名字 | 参数选项 | 参数值 | 参数释义 |
client_id | 必选 |
| 等同与appkey |
response_type | 必选 | code |
|
redirect_uri | 必选 |
| 参见redirect_uri的定义 |
state | 可选 |
| 维持应用的状态,传入值与返回值保持一致。 |
view | 可选 | 默认为web |
|
1.2 返回值说明
参数名字 | 参数选项 | 参数释义 |
code | 正常结果 | 授权码 |
error | 异常时返回 | 错误码 |
error_description | 异常时返回 | 错误描述 |
1.3获取访问令牌参数
参数名字 | 参数选项 | 参数值 | 参数释义 |
client_id | 必选 |
| appkey的值 |
client_secret | 必选 |
| appsecret |
grant_type | 必选 | authorization_code |
|
code | 必选 |
| 授权码 |
redirect_uri | 必选 |
| 参见redirect_uri的定义 |
state | 可选 |
| 维持应用的状态,传入值与返回值保持一致。 |
view | 可选 | 默认为web |
|
注:服务平台上的“立即使用”链接点击以后会传递一些信息给应用,这些参数会使用state参数传递。
参数形式如下:state=versionNo:1;itemCode:xxxxx
1.4 获取访问令牌的返回值以json格式返回
Key | 类型 | 选项 | 示例 | 说明 |
access_token | string | 必选 | 2YotnFZFEjr1zCsicMWpAA | Access token |
token_type | string | 必选 | Bearer | Access token的类型目前只支持bearer |
expires_in | number | 必选 | 10(表示10秒后过期) | Access token过期时间 |
refresh_token | string | 可选 | 2YotnFZFEjr1zCsicMWpAA | Refresh token |
re_expires_in | number | 可选 | 10(表示10秒后过期) | Refresh token过期时间 |
r1_expires_in | number | 必选 | 10(表示10秒后过期) | r1级别API或字段的访问过期时间 |
r2_expires_in | number | 必选 | 10(表示10秒后过期) | r2级别API或字段的访问过期时间 |
w1_expires_in | number | 必选 | 10(表示10秒后过期) | w1级别API或字段的访问过期时间 |
w2_expires_in | number | 必选 | 10(表示10秒后过期) | w2级别API或字段的访问过期时间 |
taobao_user_nick | string | 必选 | 淘宝测试test | 淘宝账号 |
taobao_user_id | string | 必选 | 706388888 | 淘宝帐号对应id |
sub_taobao_user_id | string | 可选 | 2343535 | 淘宝子账号对应id |
sub_taobao_user_nick | string | 可选 | 淘宝测试test:123 | 淘宝子账号 |
2.示例
2.1请求授权用户登录
2.2 请求授权用户授权(用户登录后)
2.3 获取授权码
2.4 获取访问令牌
PHP 示例 <?php /*测试时,需把test参数换成自己应用对应的值*/ $url = 'https://oauth.taobao.com/token'; $postfields= array('grant_type'=>'authorization_code', 'client_id'=>'test', 'client_secret'=>'test', 'code'=>'test', 'redirect_uri'=>'http://www.test.com'); $post_data = ''; foreach($postfields as $key=>$value){ $post_data .="$key=".urlencode($value)."&";} $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); //指定post数据 curl_setopt($ch, CURLOPT_POST, true); //添加变量 curl_setopt($ch, CURLOPT_POSTFIELDS, substr($post_data,0,-1)); $output = curl_exec($ch); $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); echo $httpStatusCode; curl_close($ch); var_dump($output); ?>
|
JAVA 示例 import java.io.IOException; import java.util.HashMap; import java.util.Map; import com.taobao.api.internal.util.WebUtils; //引用top sdk public class open_oauth { public static void main(String[] args) { String url="https://oauth.taobao.com/token"; Map<String,String> props=new HashMap<String,String>(); props.put("grant_type","authorization_code"); /*测试时,需把test参数换成自己应用对应的值*/ |
C# 示例 string url = "https://oauth.taobao.com/token"; Dictionary<string, string> props = new Dictionary<string, string>(); props.Add("grant_type", "authorization_code"); props.Add("code","code"); props.Add("client_id","test"); props.Add("client_secret", "test"); props.Add("redirect_uri", "test"); props.Add("view", "web"); string s = ""; try { WebUtils webUtils = new WebUtils(); s = webUtils.DoPost(url, props, 30000, 30000); } catch (IOException e) { |
然后把responseJson 转化为对象,或者直接从里面提取:access_token字段。
返回结果内容示例:
{ "w2_expires_in": 0, "taobao_user_id": "263685215", "taobao_user_nick": "%E5%95%86%E5%AE%B6%E6%B5%8B%E8%AF%95%E5%B8%90%E5%8F%B752", "w1_expires_in": 1800, "re_expires_in": 0, "r2_expires_in": 0, "expires_in": 86400, "token_type": "Bearer", "refresh_token": "6200e1909ca29b04685c49d67f5ZZ3675347c0c6d5abccd263685215", "access_token": "6200819d9366af1383023a19907ZZf9048e4c14fd56333b263685215", "r1_expires_in": 1800 } |
Client-side flow
1. 参数说明
1.1 获取授权码参数
参数名字 | 参数选项 | 参数值 | 参数释义 |
client_id | 必选 |
| appkey的值 |
response_type | 必选 | token |
|
redirect_uri | 可选 |
| 参见redirect_uri的定义 |
state | 可选 |
| 维持应用的状态,传入值与返回值保持一致。 |
view | 可选 | 默认为web |
|
1.2 返回值说明
Key | 类型 | 选项 | 示例 | 说明 |
access_token | string | 必选 | 2YotnFZFEjr1zCsicMWpAA | Access token |
token_type | string | 必选 | Access token的类型目前只支持bearer | |
expires_in | number | 必选 | 10(表示10秒后过期) | Access token过期时间 |
refresh_token | string | 可选 | 2YotnFZFEjr1zCsicMWpAA | Refresh token |
re_expires_in | number | 可选 | 10(表示10秒后过期) | Refresh token过期时间 |
r1_expires_in | number | 必选 | 10(表示10秒后过期) | r1级别API或字段的访问过期时间 |
r2_expires_in | number | 必选 | 10(表示10秒后过期) | r2级别API或字段的访问过期时间 |
w1_expires_in | number | 必选 | 10(表示10秒后过期) | w1级别API或字段的访问过期时间 |
w2_expires_in | number | 必选 | 10(表示10秒后过期) | w2级别API或字段的访问过期时间 |
2. 示例
2.1 请求授权用户登录
&state=1212
2.2 请求授权用户授权
2.3 获取访问令牌
if(window.location.hash!=""){alert(window.location.hash)}
2.4 验证sign
如:https://oauth.taobao.com/oauth2?view=web#access_token=61019267f9d9c4d4c724dc3f1c773391068&token_type=Bearer&expires_in=86400&refresh_token=610102609
2fb00de178e5da01e3e3b427f409773391068&re_expires_in=86400&r1_expires_in=86400&r2_expires_in=86400&taobao_user_id=77339
1068&taobao_user_nick=BAcharlie&w1_expires_in=86400&w2_expires_in=86400&state=123123&top_sign=A4AF4AF132DAB8AD259645D
18C
把井号之后的参数进行拼接,access_token61019267f9d9c4d4c724dc3f1c773391068token_typeBearerexpires_in86400refresh_token6101026092fb00de178e5da01e3e
3b427f409773391068re_expires_in86400r1_expires_in86400r2_expires_in86400taobao_user_id773391068taobao_user_nickBAcharliew1_
expires_in86400w2_expires_in86400state123123 然后加上secret做签名 。
Native Application
1.参数说明
1.1 获取授权码参数
参数名字 | 参数选项 | 参数值 | 参数释义 |
client_id | 必选 |
| appkey的值 |
response_type | 必选 | code |
|
redirect_uri | 必选 | urn:ietf:wg:oauth:2.0:oob |
|
state | 可选 |
| 维持应用的状态,传入值与返回值保持一致。 |
view | 可选 | 默认为web |
|
1.2 获取访问令牌参数
参数名字 | 参数选项 | 参数值 | 参数释义 |
client_id | 必选 |
| appkey的值 |
client_secret | 必选 |
| appsecret |
grant_type | 必选 | authorization_code |
|
code | 必选 |
| 授权码 |
redirect_uri | 必选 | urn:ietf:wg:oauth:2.0:oob | 参见redirect_uri的定义 |
state | 可选 |
| 维持应用的状态,传入值与返回值保持一致。 |
view | 可选 | 默认为web |
|
2.应用示例
2.1 请求授权用户登录
2.2 请求授权用户授权
2.3 获取授权码
2.4 获取访问令牌
Map<String, String> param = new HashMap<String, String>();
param.put(“grant_type”, "authorization_code");
param.put(“code”, 授权码);
param.put(“client_id”, appKey);
param.put(“client_secret”, appSecret);
param.put(“redirect_uri”, redirect_uri);
param.put(“view”, “web”);
param.put(“state”, state);
String responseJson=WebUtils.doPost(tbPostSessionUrl, param, 3000, 3000);
然后把responseJson 转化为对象,或者直接从里面提取:access_token字段。
返回结果内容示例:
{ "w2_expires_in": 0, "taobao_user_id": "263685215", "taobao_user_nick": "%E5%95%86%E5%AE%B6%E6%B5%8B%E8%AF%95%E5%B8%90%E5%8F%B752", "w1_expires_in": 1800, "re_expires_in": 0, "r2_expires_in": 0, "expires_in": 86400, "token_type": "Bearer", "refresh_token": "6200e1909ca29b04685c49d67f5ZZ3675347c0c6d5abccd263685215", "access_token": "6200819d9366af1383023a19907ZZf9048e4c14fd56333b263685215", "r1_expires_in": 1800 } |
Refreshing an Access Token
1.参数说明
参数名字 | 参数选项 | 参数值 | 参数释义 |
client_id | 必选 |
| appkey的值 |
client_secret | 必选 |
| appsecret |
grant_type | 必选 | refresh_token |
|
refresh_token | 必选 |
| 授权颁发的刷新令牌 |
state | 可选 |
| 维持应用的状态,传入值与返回值保持一致。 |
view | 可选 | 默认为web |
|
2.应用示例
Map<String, String> param = new HashMap<String, String>();
param.put(“grant_type”, " refresh_token ");
param.put(“refresh_token”, refreshToken);
param.put(“client_id”, appKey);
param.put(“client_secret”, appSecret);
param.put(“view”, “web”);
param.put(“state”, state);
String responseJson=WebUtils.doPost(tbPostSessionUrl, param, 3000, 3000);
然后把responseJson 转化为对象,或者直接从里面提取:access_token字段以及新的刷新令牌
返回结果内容示例:
{ "w2_expires_in": 0, "taobao_user_id": "263685215", "taobao_user_nick": "%E5%95%86%E5%AE%B6%E6%B5%8B%E8%AF%95%E5%B8%90%E5%8F%B752", "w1_expires_in": 1800, "re_expires_in": 0, "r2_expires_in": 0, "expires_in": 86400, "token_type": "Bearer", "refresh_token": "6200e1909ca29b04685c49d67f5ZZ3675347c0c6d5abccd263685215", "access_token": "6200819d9366af1383023a19907ZZf9048e4c14fd56333b263685215", "r1_expires_in": 1800 } |
登录帐号退出流程
参数说明
参数名字 | 参数选项 | 参数值 | 参数释义 |
client_id | 必选 |
| appkey的值 |
view | 可选 | 只支持web |
|
示例:
附录
无线端登录授权页面:
错误码排查
错误信息 | 错误原因 |
request method must be get | 该请求必须用GET方法 |
request method must be post | 该请求必须用POST方法 |
client_id is empty | client_id(即appkey)不能为空 |
response_type is empty | response_type不能为空 |
redirect_uri is empty | redirect_uri不能为空 |
grant type is empty | grant type不能为空 |
authorize code is empty | authorize code不能为空 |
unsupported response type,the response type must code or token | response type的值必须为code或者token |
redirect_uri is invalidate | redirect_uri校验失败,请检查你在开发者中心注册的回调地址和redirect_uri是否一致 |
the grant type unsupported | grant type值无效 |
authorize reject | 用户拒绝授权 |
authorize code expire | authorize code失效,请重新授权 |
authorize code xxxx invalidate,please authorize again. | authorize code失效,请重新授权 |
client_secret is invalidate | app secret校验失败 |
xss chars included in params, such as <, >, ', " | 请求参数中带有以下字符:<, >, ', " |
The Application already Bind with user ids:xxx | APP已经绑定了用户xxx。请到开发者中心“授权管理”页面设置绑定的用户nick |
Can not find the client_id:xxxxx | client_id(即appkey)不存在 |
Application need publish | 只有状态为“正式环境测试”和“上线运行中”的应用才允许授权 |
Application xxx need purchase | 必须先订购才能使用 |
app call back is invalidate | 应用的回调地址不合法 |
application callback can not match the redirect_uri | redirect_uri和事先配置的回调地址不匹配 |
only support http or https | 回调URL只支持https或http协议 |
application in black list,access forbidden. | app存在黑名单中 |
application session type must be common | session key类型不正确(只支持现有的常规sessionkey和订购类型sessionkey) |
The application don't need session | 此应用不需要session key,不用刷新session key |
session key num is larger than xx | 有效session key个数超过上限 |
userid is invalidate | userId 不存在 |
login failure | 用户登录失败 |
login sign failure | 无线登录签名校验失败 |
taobao staff can't accredit | 淘宝小二不允许访问 |
subuser can't access | 应用不支持子账号访问 |
parent account forbid this sub account to access app. | 父账号未授权此子账号访问应用 |
parent account forbidden | 父账号未授权或授权已过期 |
refresh token is empty | refresh token为空 |
refresh token is error:xxxx | refresh token内容有误解析失败 |
refresh token is invalid | refresh token已经失效 |
refresh times limit exceed | 刷新次数超过上限,一个session key一天最多可刷新60次 |
session expire | 当前会话已经过期,可能用户浏览器暂停太久已经超时 |
OAUTH SERVER ERROR:xxxxx | 系统内部错误,请重试 |
Iossdk params is lack | 缺少ios sdk协议参数 |
iossdk track_id is invalid | ios sdk协议参数track id校验失败。建议核对一下app secret |
iossdk params check failed | ios sdk协议参数校验失败 |