OAuth2 客户端授权¶
如果用户在大象客户端工作台中访问第三方微应用,第三方微应用可以通过大象OAuth2网页授权机制,来获取用户基本信息,进而实现业务逻辑。 大象OAuth2网页授权流程主要分为4步:
- 引导用户进入授权页面同意授权,获取code
- 通过code换取网页授权access_token
- 如果需要,开发者可以通过refresh_token刷新网页授权access_token,避免过期
- 通过网页授权access_token获取用户基本信息
一. 术语表¶
term | 解释说明 |
---|---|
authorize server | 提供用户授权页面,code换取access token ,refresh token刷新access token等功能 |
resource server | 为第三方服务提供业务数据接口,会验证请求中的access token及其对应的权限信息 |
app_key | 创建微应用时获取的key |
app_secret | 创建微应用时获取的token,与appKey共同作为第三方服务与authorize server之间通信认证basic auth的基础 |
authorize code | 用户授权后,authorize server发送给第三方服务,第三方服务以此换取access token |
access token | 第三方服务器访问资源服务器时需要提供的权限凭证 |
二. 开发流程¶
简要时序图¶
OAuth2流程展示¶
1. 用户同意授权,获取authorize code¶
在确保微应用拥有授权作用域(scope参数)的权限的前提下,引导用户打开如下页面:
https://open.neixin.cn/oauth/v2/authorize?app_key=${appKey}&redirect_uri=${redirect_uri}&response_type=code&state=${state}
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
app_key | 是 | 微应用appKey |
redirect_uri | 是 | 授权后重定向的回调链接地址,即第三方微应用的地址,请使用urlencode对链接进行处理,尽量使用https协议以保证authroize code的安全性. |
response_type | 是 | 返回类型,请填写code |
scope | 是 | 授权范围,目前仅有两种.USER_INFO:用户基础信息包含passport,name,gender,avatar,PHONE_NUMBER:用户手机.可以多选,多选时用空格做分隔符,且使用空格的url编码格式%20 |
state | 是 | 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 |
下图为scope=USER_INFO PHONE_NUMBER时显示的授权页
用户同意授权后
如果用户同意授权,页面将跳转至${redirect_uri}/?code=CODE&state=${STATE}
.若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=${STATE}
code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
2. 通过code换取网页授权access_token¶
*由于微应用的appSecret以及access_token的安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。 *
请求方法
获取code后,通过POST方式向https://api.neixin.cn/oauth/v2/api/token获取access_token.
curl\ -s\ -X POST\ "https://api.neixin.cn/oauth/v2/api/token?app_key=${appKey}&app_secret=${app_secret}&code=${code}&state=${state}&grant_type=authorization_code&redirect_uri=${redirect_uri}"
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
code | 是 | 填写第一步获取的code参数 |
grant_type | 是 | 填写为authorization_code,state 是与上一步state相同 |
redirect_uri | 是 | 与上一步的redirect_uri相同 |
返回说明
正确时(rescode=0)返回的JSON数据如下:
{ "rescode": 0, "data": { "access_token": "ACCESS_TOKEN", "expires_in": 7200, "refresh_token": "REFRESH_TOKEN", "scope": "SCOPE", "token_type": "bear" } }
字段 | 描述 |
---|---|
access_token | 网页授权接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
scope | 用户授权的作用域,使用空格分隔 |
token_type | token使用方式目前仅支持bearer(持有)类型 |
错误时(rescode!=0)授权服务器会返回JSON数据包如下(示例为Code无效错误):
{ "data": { "message": "Invalid authorization code:123dad" }, "rescode": 20013 }
3. 刷新access_token¶
由于access_token拥有较短的有效期(7天),当access_token超时后,可以使用refresh_token进行刷新,refresh_token拥有较长的有效期(7天、30天、60天、90天),当refresh_token失效的后,需要用户重新授权。
请求方法
获取第二步的refresh_token后,可以继续通过https://api.neixin.cn/oauth/v2/api/token刷新access_toke
curl\ -s\ -X POST \ "https://api.neixin.cn/oauth/v2/api/token?app_key=${appKey}&app_secret=${appSecret}&grant_type=refresh_token&refresh_token=${refresh_token}"
参数 | 是否必须 | 说明 |
---|---|---|
grant_type | 是 | 填写为refresh_token |
refresh_token | 是 | 填写通过access_token获取到的refresh_token参数 |
返回说明
正确时(rescode=0)返回的JSON数据包如下
{ "data" : { "refresh_token" : "63d0071d-77b2-4df2-8e6d-e9e2029a5974", "access_token" : "124c862b-e9c3-4061-a34c-adf2c896eeb3", "expires_in" : 604613, "scope" : "PHONE_NUMBER USER_INFO", "token_type" : "bearer" }, "rescode" : 0 }
字段 | 描述 |
---|---|
access_token | 网页授权接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
scope | 用户授权的作用域,使用空格分隔 |
token_type | token使用方式目前仅支持bearer(持有)类型 |
错误时(rescode!=0)授权服务器会返回JSON数据包如下 |
{ "data": { "message": "Invalid refresh token (expired): D29DXff9aaJHNL" }, "rescode": 20021 }
4. 拉取用户信息¶
请求方法
获取到access_token后即可通过POST方式向 https://api.neixin.cn/oauth/v2/api/resource/get_phonenumber, https://api.neixin.cn/oauth/v2/api/resource/get_userinfo 获取用户电话及基础信息
curl -s https://api.neixin.cn/oauth/v2/api/resource/get_phonenumber?access_token=${accessToken}
curl -s https://api.neixin.cn/oauth/v2/api/resource/get_userinfo?access_token=${accessToken}
返回说明
正确时(rescode=0)返回的JSON数据包如下:
{ "rescode" : 0, "data" : { "phone_number":"12312313123" } }
{ "rescode" : 0, "data" : { "uinfo" : { "gender" : "1", "user_id":"xiangshuai", "cid":1, "name" : "相帅", "big_avatar_url" : "http://msstestdn.sankuai.com/v1/mss_37ed3a16b0594c9fb747ff29d3d087e8/profile4/3988a624-ae32-4f07-8d8c-14785b754ffe" } } }
错误时(rescode!=0)授权服务器会返回JSON数据包如下:
{ "data" : { "message" : "xxxxx" }, "rescode" : 20013 }
三. 附录¶
错误码说明¶
rescode | 简要说明 | 解释 |
---|---|---|
20001 | BadClientCredentialsException | 微应用服务BA认证失败 |
20002 | ClientAuthenticationException | 微应用服务BA认证失败 |
20003 | ForbiddenException | 禁止请求 |
20004 | InsufficientScopeException | 请求的scope列表中包含了未分配给微应用的scope |
20005 | InvalidClientException | 微应用服务BA认证失败 |
20006 | InvalidGrantException | 授权失败 |
20007 | InvalidRequestException | 非法请求 |
20008 | InvalidScopeException | 请求的scope列表中包含了非法的scope |
20009 | InvalidTokenException | 非法accessToken, |
20010 | MethodNotAllowed | HTTP方法错误 |
20011 | OAuth2AccessDeniedException | oauth接入错误 |
20012 | RedirectMismatchException | 微应用使用了未在开放平台注册的域名 |
20013 | ServerErrorException | 服务器异常,请联系管理员. |
20014 | UnauthorizedClientException | 微应用尚未授信 |
20015 | UnauthorizedException | 未授信 |
20016 | UnauthorizedUserException | 用户尚未授信 |
20017 | UnsupportedGrantTypeException | 微应用请求了未被支持的授权类型,请检查引导用户授权时grant_type参数是否为authorization_code,以及refresh token时grant_type是否为refresh_token |
20018 | UnsupportedResponseTypeException | 请求期望了错误的响应类型 |
20019 | UserDeniedAuthorizationException | 用户拒绝授权 |
20020 | ExpiredAccessTokenException | access token过期,需要refresh token或者引导用户重新授权 |
20021 | ExpiredRefreshTokenException | refresh token过期,需要引导用户重新授权 |
access token转jsTicket¶
echo -n $(echo -n ${accessToken}|base64)|md5