OAuth2 客户端授权

如果用户在大象客户端工作台中访问第三方微应用,第三方微应用可以通过大象OAuth2网页授权机制,来获取用户基本信息,进而实现业务逻辑。 大象OAuth2网页授权流程主要分为4步:

  1. 引导用户进入授权页面同意授权,获取code
  2. 通过code换取网页授权access_token
  3. 如果需要,开发者可以通过refresh_token刷新网页授权access_token,避免过期
  4. 通过网页授权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"
   }
}
user_id和cid两者确定一个唯一的用户,各业务一定要注意此处,避免引起身份混乱
{
   "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