假如使用uni-app开发一款小程序,它同时被使用在钉钉,企业微信,微信中,要表现同一功能,开发的时候该如何兼容它们之间的差异呢?在这里,以三种环境获取手机号为例,分别了解获取流程,代码实现的差异。
钉钉获取手机号流程
我们使用的场景是:开发企业内应用,希望获取用户个人信息,如用户个人手机号、个人邮箱、钉钉头像URL等。
一、首先的申请权限,在调用需授权才能访问的服务端API时,如果用户未授权,会返回错误码60011或没有返回期望的某些信息。下两种权限:
-
需要申请接口权限-获取用户通讯录个人信息
-
需要申请字段权限-个人手机号信息权限
二、客户端获取authCode,调用获取用户token接口,换取用户个人access_token。
请求接口及参数
POST /v1.0/oauth2/userAccessToken HTTP/1.1
Host:api.dingtalk.com
Content-Type:application/json
{
"clientId" : "String", // 企业内部应用传应用的AppKey
"clientSecret" : "String", // 企业内部应用传应用的AppSecret
"code" : "String", // 临时授权码
"refreshToken" : "String",
"grantType" : "String"
}
返回结果示例:
HTTP/1.1 200 OK
Content-Type:application/json
{
"accessToken" : "abcd",
"refreshToken" : "abcd",
"expireIn" : 7200,
"corpId" : "corpxxxx"
}
三、使用获取的用户个人access_token,调用获取用户通讯录个人信息接口,获取用户个人手机号、用户的钉钉昵称、头像URL、用户的个人邮箱等信息。
请求参数
GET /v1.0/contact/users/{unionId} HTTP/1.1
Host:api.dingtalk.com
x-acs-dingtalk-access-token:String
Content-Type:application/json
// 请求头参数
x-acs-dingtalk-access-token:调用服务端接口的授权凭证。使用个人用户的accessToken,请参考获取登录用户的访问凭证。
// path参数
unionId:用户的unionId。如需获取当前授权人的信息,unionId参数可以传me。
返回示例
HTTP/1.1 200 OK
Content-Type:application/json
{
"nick" : "zhangsan",
"avatarUrl" : "https://xxx",
"mobile" : "150xxxx9144",
"openId" : "123",
"unionId" : "z21HjQliSzpw0Yxxxx",
"email" : "zhangsan@alibaba-inc.com",
"stateCode" : "86"
}
流程示意图如下:
企业微信获取手机号流程
一、客户端获取临时登录凭证code
可直接从客户端获取code
二、获取access_token
请求接口
// 请求方式
GET(HTTPS)
// 请求URL
https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
// 参数
corpid:企业ID
corpsecret:应用的凭证密钥
返回示例:
{
"errcode":0,
"errmsg":"",
"access_token": "accesstoken000001",
"expires_in": 7200
}
三、获取userid
通过临时登录凭证校验接口获取userid,临时登录凭证校验接口是一个服务端HTTPS 接口,开发者服务器使用临时登录凭证code获取 session_key、用户userid以及用户所在企业的corpid等信息。
请求方式:
// 方式
GET(HTTPS)
// 地址
https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session?access_token=ACCESS_TOKEN&js_code=CODE&grant_type=authorization_code
// 参数
access_token:调用接口凭证(注意,此处的access_token 是企业微信应用的access_token,获取方法参见“获取access_token”。要求必须由该小程序关联的企业微信应用的secret获取
js_code:登录时获取的 code
grant_type:此处固定为authorization_code
返回示例:
{
"corpid": "CORPID",
"userid": "USERID",
"session_key": "kJtdi6RF+Dv67QkbLlPGjw==",
"errcode": 0,
"errmsg": "ok"
}
四、通过服务端api->通讯录管理->成员管理->读取成员接口,获取成员信息,包含手机号
请求方式:
// 请求方式
GET(HTTPS)
// 请求地址
https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&userid=USERID
// 参数
access_token:调用接口凭证-二步中获取的
userid:成员UserID-三步中获取的
返回体参见:这里
流程示意图如下:
微信获取手机号流程
一、获取code
需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到动态令牌code,然后把code传到开发者后台,并在开发者后台调用微信后台提供的 phonenumber.getPhoneNumber 接口,消费code来换取用户手机号。每个code有效期为5分钟,且只能消费一次。
示例:
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
//
Page({
getPhoneNumber (e) {
console.log(e.detail.code)
}
})
返回参
二、获取access_token
获取小程序全局唯一后台接口调用凭据(access_token)。调用绝大多数后台接口时都需使用 access_token,开发者需要进行妥善保存。 如使用云开发,可通过云调用免维护 access_token 调用。如使用云托管,也可以通过微信令牌/开放接口服务免维护 access_token 调用。
请求地址
// 接口
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
// 参数
grant_type:填写 client_credential
appid:小程序唯一凭证,即 AppID,可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态)
secret:小程序唯一凭证密钥,即 AppSecret,获取方式同 appid
返回结果
{"access_token":"ACCESS_TOKEN","expires_in":7200}
三、调用phonenumber.getPhoneNumber获取手机号
请求地址:
POST https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN
// 参数是一,二中获取的值
返回示例:
{
"errcode":0,
"errmsg":"ok",
"phone_info": {
"phoneNumber":"xxxxxx",
"purePhoneNumber": "xxxxxx",
"countryCode": 86,
"watermark": {
"timestamp": 1637744274,
"appid": "xxxx"
}
}
}
代码实现差异
钉钉,企业微信,微信均不允许前端直接调用获取access_token等信息,所有接口均在服务端完成。客户端提供临时登录凭证code,下面以uni-app的实现方式为例,看下三种实现方式的差异。
获取code(针对获取手机号)
// 钉钉
uni.login({
success: res => {
if (res.authCode || res.code) {}
}
})
// 企业微信(uniapp未提供企业微信获取code的方法,使用uni.login会默认使用微信小程序的方式,这样获取的code在企业微信里是无法使用的)
wx.qy.login({
success: res => {
if (res.authCode || res.code) {}
}
})
// 微信
<button open-type="getPhoneNumber" @getphonenumber="getphonenumber">微信一键登录</button>
getphonenumber回调中有code
至此,可以了解到三种环境获取手机号的不同,差异主要还是服务端的接口调用,流程大致相同,要先得到凭证,应用秘钥,应用的key,企业ID等。