简体中文
获取一键登录管理对象 已废弃,仅为了向下兼容保留,建议使用getUniVerifyManager
。
Web | 微信小程序 | Android | iOS |
---|---|---|---|
x | - | 3.99 | 4.18 |
App一键登录,封装了个推的一键登录sdk,其内部再次封装了中国三大电信运营商提供的sdk。通过运营商提供的服务,可以在手机sim卡信号正常的情况下,通过云端接口获取到当前用户的手机号。
使用一键登录可以点一下直接以当前手机号登录。不再需要短信验证码,而且费用比短信验证码便宜。
App一键登录的优势:
一键登录涉及业务开通和付费,因为安全问题又涉及客户端和服务器交互,有较多文档:
uni-id-pages插件,已经内置一键登录,从云端到客户端均已开发好并开源,推荐使用。详情
一键登录有标准登录模式(login方法)和自定义登录模式(customLogin方法)。标准模式是uni-app封装好的UI界面,自定义模式是开发者自己布局界面。见下
WARNING
从HBuilderX 4.41+,UniverifyManager的方法的参数类型
进行了调整。
比如之前类型叫LoginOptions
,改名为了UniVerifyManagerLoginOptions
,加上了UniVerifyManager
前缀。
本调整是因为未来会增加更多登录方式,一键登录的参数类型占用通用的名称LoginOptions
不合适。
涉及名单如下:
注意在4.41以前的版本,仍需使用无前缀的老类型名称。
一般情况下,开发者无需手动 as 返回值类型,uni-app x 会自动推导类型。早期的示例代码有 as ,新版示例已经去掉。
类型 |
---|
UniverifyManager |
预登录
Web | 微信小程序 | Android | iOS |
---|---|---|---|
- | - | 3.99 | 4.18 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | UniVerifyManagerPreLoginOptions | 是 | - | - | 预登录参数 | ||||||||||||||||||||||||
|
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
number | string | 是 | - | 手机号(脱敏) | |
slogan | string | 是 | - | 运营商slogan,如移动:中国移动提供认证服务,联通:认证服务由联通统一认证提供,电信:天翼账号提供认证服务 | |
privacyName | string | 是 | - | 运营商隐私协议名称,如移动:中国移动认证服务条款,联通:联通统一认证服务条款,电信:天翼账号服务与隐私协议 | |
privacyUrl | string | 是 | - | 运营商隐私协议url地址 |
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
errCode | number | 是 | - | - | 错误码 | ||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||
errSubject | string | 是 | - | - | 统一错误主题(模块)名称 | ||||||||||||||||||||||||||||||||||||||||||
data | any | 否 | - | - | 错误信息中包含的数据 | ||||||||||||||||||||||||||||||||||||||||||
cause | Error | 否 | - | - | 源错误信息,可以包含多个错误,详见SourceError | ||||||||||||||||||||||||||||||||||||||||||
errMsg | string | 是 | - | - | - |
标准登录
Web | 微信小程序 | Android | iOS |
---|---|---|---|
- | - | 3.99 | 4.18 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | UniVerifyManagerLoginOptions | 是 | - | - | 登录参数 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
openId | string | 是 | - | - | 登录授权唯一标识 |
accessToken | string | 是 | - | - | token |
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
errCode | number | 是 | - | - | 错误码 | ||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||
errSubject | string | 是 | - | - | 统一错误主题(模块)名称 | ||||||||||||||||||||||||||||||||||||||||||
data | any | 否 | - | - | 错误信息中包含的数据 | ||||||||||||||||||||||||||||||||||||||||||
cause | Error | 否 | - | - | 源错误信息,可以包含多个错误,详见SourceError | ||||||||||||||||||||||||||||||||||||||||||
errMsg | string | 是 | - | - | - |
自定义授权页登录
Web | 微信小程序 | Android | iOS |
---|---|---|---|
- | - | 4.41 | 4.41 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | UniVerifyManagerCustomLoginOptions | 是 | - | - | 自定义登录页登录参数 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
关闭授权页(仅支持标准登录)
Web | 微信小程序 | Android | iOS |
---|---|---|---|
- | - | 3.99 | 4.18 |
预登录是否有效
Web | 微信小程序 | Android | iOS |
---|---|---|---|
- | - | 3.99 | 4.18 |
类型 |
---|
boolean |
上述API不管是预登录还是登录,失败时返回的uni Error错误对象,有一个属性cause,它表示底层的错误来源,这里包含了个推的个验sdk和运营商sdk的详细信息。比如没有sim卡或未开启蜂窝网络。
在大多数情况下,开发者需要把这些更为详细的错误提示给用户,以引导用户正确使用一键登录。
错误码 | 错误信息 |
---|---|
-10000 | sdk没有初始化,请先初始化sdk |
-10001 | sdk初始化失败,详见整体msg内容 |
-10003 | 接口请求超时,请稍后重试、加大超时时间或者检查网络 |
-10006 | 上一个请求正在进行中,请稍后重试 |
-10009 | 其他错误,详见整体msg内容,比如metadata字段等会有更详细的内容 |
-20100 | 传入参数错误 |
-20101 | appid为空,请检查 build.gradle 字段 GETUI_APPID |
-20102 | appid无效或者签名无效 |
-20104 | 预登录无效,请先进行预登录 |
-20200 | 无网络可用,请检查手机网络、或者稍后重试 |
-20201 | 未插手机电话卡 |
-20202 | 未开启蜂窝网络 |
-20203 | 不支持的运营商,请检查手机是否成功连接运营商、以及sdk支持该运营商 |
-20301 | 登录授权页退出 |
-20500 | 获取运营商APPID失败,请重启应用重试、或者联系技术支持 |
-30001 | 服务器返回的其他错误,详见整体msg内容 |
-40001 | 运营商返回的其他错误,详见整体msg内容,比如metadata字段等会有更详细的内容 |
错误码 | 错误信息 |
---|---|
102101 | 无网络 |
102102 | 网络异常 |
102103 | 未开启数据网络 |
102203 | 输入参数错误 |
102223 | 数据解析异常,一般是卡欠费 |
102507 | 登录超时(授权页点登录按钮时) |
103101 | 请求签名错误(若发生在客户端,可能是 appkey 传错,可检查是否跟 appsecret 弄混,或者有空格。若发生在服务端接口,需要检查验签方式是 MD5 还是 RSA,如果是 MD5,则排查 signType 字段,若为 appsecret,需确认是否误用了 appkey 生签。如果是 RSA,需要检查使用的私钥跟报备的公钥是否对应和报文拼接是否符合文档要求。) |
103102 | 包签名错误(社区填写的 appid 和对应的包名包签名必须一致) |
103111 | 网关 IP 错误(检查是否开了 vpn 或者境外 ip) |
103119 | appid 不存在(检查传的 appid 是否正确或是否有空格) |
103211 | 其他错误,(常见于报文格式不对,先请检查是否符合这三个要求:a、json 形式的报文交互必须是标准的 json 格式;b、发送时请设置content type 为 application/json;c、参数类型都是 String。如有需要请联系 qq 群 609994083 内的移动认证开发) |
103412 | 无效的请求(1.加密方式错误;2.非 json 格式;3.空请求等) |
103414 | 参数校验异常 |
103511 | 服务器 ip 白名单校验失败 |
103811 | token 为空 |
103902 | scrip 失效(客户端高频调用请求 token 接口) |
103911 | token 请求过于频繁,10 分钟内获取 token 且未使用的数量不超过30 个 |
104201 | token 已失效或不存在(重复校验或失效) |
105001 | 联通取号失败 |
105002 | 移动取号失败(一般是物联网卡) |
105003 | 电信取号失败 |
105012 | 不支持电信取号 |
105013 | 不支持联通取号 |
105018 | token 权限不足(使用了本机号码校验的 token 获取号码) |
105019 | 应用未授权(未在开发者社区勾选能力) |
105021 | 当天已达取号限额 |
105302 | appid 不在白名单 |
105312 | 余量不足(体验版到期或套餐用完) |
105313 | 非法请求 |
200002 | 用户未安装 sim 卡 |
200010 | 无法识别 sim 卡或没有 sim 卡 |
200023 | 请求超时 |
200005 | 用户未授权(READ_PHONE_STATE) |
200020 | 授权页关闭 |
200021 | 数据解析异常(一般是卡欠费) |
200022 | 无网络 |
200023 | 请求超时 |
200024 | 数据网络切换失败 |
200025 | 其他错误(socket、系统未授权数据蜂窝权限等,如需要协助,请加入 qq 群发问) |
200026 | 输入参数错误 |
200027 | 未开启数据网络或网络不稳定 |
200028 | 网络异常 |
200038 | 异网取号网络请求失败 |
200039 | 异网取号网关取号失败 |
200040 | UI 资源加载异常 |
200050 | EOF 异常 |
200072 | CA 根证书校验失败 |
200080 | 本机号码校验仅支持移动手机号 |
200082 | 服务器繁忙 |
200087 | 授权页成功调起 |
错误码 | 错误信息 |
---|---|
100 | 应用未授权 |
101 | 应用秘钥错误 |
102 | 应用无效 |
103 | 应用未授权该 IP 访问 |
104 | 应用访问次数不足 |
105 | 应用包名不正确 |
106 | 应用状态非法 |
107 | 商户状态非法 |
108 | 商户请求次数超限额 |
200 | tokenId 无效 |
201 | token 已失效 |
202 | token 未授权该应用访问 |
203 | 登录鉴权级别不满足接口鉴权要求 |
300 | 接口未开放 |
301 | 应用未授权码访问该接口 |
302 | IP 未授权码访问该接口 |
303 | 应用访问接口次数超日限额 |
400 | 请求参数为空 |
401 | 请求参数不完整 |
402 | 请求参数非法 |
600 | 请求非法 |
1000 | 请求解析错误 |
1001 | 请求已失效 |
1002 | 验签失败 |
1003 | 授权码已过期 |
1004 | 加密方式不支持 |
1005 | RSA 加密错误 |
1010 | 服务间访问失败 |
1011 | 服务间访问错误 |
3010 | 网关取号错误 |
3012 | 网关取号失败 |
3013 | 电信网关取号失败 |
3014 | 电信网关取号错误 |
3016 | 移动网关取号失败 |
3017 | 移动网关取号错误 |
3050 | 取号网关内部错误 |
3057 | 网关鉴权码查找号码失败 |
3058 | 网关鉴权码格式错误 |
3059 | 网关鉴权码已失效 |
3060 | 网关账号认证失败 |
3061 | 网关取号配额不足 |
3062 | IP 未授权访问网关 |
3063 | 网关并发连接数受限 |
3064 | 访问网关参数非法 |
3065 | 未授权访问该网关能力 |
3066 | 网关服务暂时不可用 |
错误码 | 错误信息 |
---|---|
-64 | permission-denied(无权限访问) |
-65 | API-request-rates-Exceed-Limitations(调用接口超限) |
-10001 | 取号失败 |
-10002 | 参数错误 |
-10003 | 解密失败 |
-10004 | ip受限 |
-10005 | 异网取号回调参数异常 |
-10006 | Mdn取号失败,且属于电信网络 |
-10007 | 重定向到异网取号 |
-10008 | 超过预设取号阈值 |
-10009 | 时间戳过期 |
-20005 | sign-invalid(签名错误) |
-20006 | 应用不存在 |
-20007 | 公钥数据不存在 |
-20100 | 内部解析错误 |
-20102 | 加密参数解析失败 |
-30001 | 时间戳非法 |
-30003 | topClass失效,请查看5.3+5.4常见问题。 |
51002 | 参数为空 |
51114 | 无法获取手机号数据 |
80000 | 请求超时 |
80001 | 请求网络异常 |
80002 | 响应码错误 |
80003 | 无网络连接 |
80004 | 移动网络未开启 |
80005 | Socket超时异常 |
80006 | 域名解析异常 |
80007 | IO异常 |
80008 | No route to host |
80009 | nodename nor servname provided, or not known |
80010 | Socket closed by remote peer |
80100 | 登录结果为空 |
80101 | 登录结果异常 |
80102 | 预登录异常 |
80103 | SDK未初始化 |
80104 | 未调用预登录接口 |
80105 | 加载nib文件异常 |
80200 | 用户关闭界面 |
80201 | 其他登录方式 |
80800 | WIFI切换异常 |
80801 | WIFI切换超时 |
三大电信运营商对一键登录在App端如何使用有一套规范,开发者必须遵守这套规范,否则会被停止服务。
uni-app x为开发者提供了两种使用方式来合规的使用一键登录:
uni-app框架预置了一个全屏和半屏的界面模板,该页面已经遵守了运营商的规范。
开发者的代码首先调用预登录,预登录成功后,调用login
方法拉起授权页面,登录成功后通过close
方法关闭页面。
此方式的优点是方便快捷、无需开发界面UI,缺点是预置页面无法自定义。
HBuilderX 4.41+
调用预登录接口如果成功,会返回4项内容:
开发者需要根据运营商的规范要求在自己的登录页面上呈现上述信息。
运营商对一键登录界面的规范要求是,页面必须有5个UI要素,包括:
uvue页面放置好上述5个UniElement后,在页面的登录按钮点击事件内调用customLogin
方法,入参传入上述五个UI元素的UniElement对象。uni-app x框架会校验这些UniElement是否遵守了运营商规范。
如果不符合规范会抛出错误(见错误码表),如符合规范会继续调用运营商的接口。
注意:如果使用三方UI库里的checkbox和button组件,可能无法获取到正确的UniCheckboxElement和UniButtonElement。此时建议改用uni-app x的标准内置组件。
登录成功后通过uni.navigateBack()
或uni.closeDialogPage()
等方式关闭授权页。
hello uni-app x里有完整的自定义登录的示例代码,该示例中:
customLogin
方法。登录成功后调用uni.closeDialogPage()
关闭。该 API 不支持 Web,请运行 hello uni-app x 到 App 平台体验
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-btn-v uni-common-mt">
<button type="default" @click="verify(false)">一键登录(半屏)</button>
</view>
<view class="uni-btn-v uni-common-mt">
<button type="default" @click="verify(true)">一键登录(全屏)</button>
</view>
<view class="uni-btn-v uni-common-mt">
<button type="default" @click="customLoginIn()">一键登录(自定义页面)</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: '一键登录',
univerifyManager: null as UniverifyManager | null,
phone: '',
slogan: '',
privacyName: '',
privacyUrl: ''
}
},
onLoad() {
this.univerifyManager = uni.getUniverifyManager();
// 预登录
this.preLogin(() => { });
},
methods: {
customLoginIn() {
const isPreLoginValid = this.univerifyManager?.isPreLoginValid() ?? false;
if (isPreLoginValid) {
this.pushCustomPage();
} else {
this.preLogin(() => {
this.pushCustomPage();
})
}
},
pushCustomPage() {
const url = '/pages/API/get-univerify-manager/univerify-custom-page?phone=' + this.phone + '&slogan=' + this.slogan + '&name=' + this.privacyName + '&link=' + this.privacyUrl;
uni.openDialogPage({
url: url,
animationType: 'slide-in-bottom',
success(res) {
console.log("成功打开自定义登录页面");
},
fail(err) {
console.log(err);
}
})
},
verify(fullScreen : boolean) {
// 校验预登录是否有效
const isPreLoginValid = this.univerifyManager?.isPreLoginValid() ?? false;
if (isPreLoginValid) {
// 预登录有效,执行登录
this.login(fullScreen);
} else {
// 预登录无效,执行预登录
this.preLogin(() => {
this.login(fullScreen);
})
}
},
preLogin(callback: (() => void)) {
this.univerifyManager?.preLogin({
success: (res) => {
this.phone = res.number;
this.slogan = res.slogan;
this.privacyName = res.privacyName;
this.privacyUrl = res.privacyUrl;
console.log("pre login success");
callback();
},
fail: (err) => {
console.error("pre login fail => " + JSON.stringify(err));
uni.showModal({
title: '预登录失败',
content: JSON.parseObject(err.cause?.cause?.message ?? "")?.getString("errorDesc") ?? err.errMsg,
showCancel: false
});
}
});
},
login(fullScreen : boolean) {
this.univerifyManager?.login({
univerifyStyle:{
fullScreen: fullScreen,
backgroundColor: "#FFFFFF",
loginBtnText: "一键登录",
logoPath: "/static/logo.png"
},
success: (res) => {
console.log("login success => " + JSON.stringify(res));
this.takePhoneNumber(res.accessToken,res.openId);
},
fail: (err) => {
console.error("login fail => " + err);
uni.showModal({
title: '登录失败',
content: JSON.parseObject(err.cause?.cause?.message ?? "")?.getString("errorDesc") ?? err.errMsg,
showCancel: false
});
}
});
},
takePhoneNumber(accessToken : string, openId : string) {
// 云函数取号
uniCloud.callFunction({
name: 'univerify',
data: {
access_token: accessToken, // 客户端一键登录接口返回的access_token
openid: openId // 客户端一键登录接口返回的openid
}
}).then(res => {
// 关闭登录页
this.univerifyManager?.close();
setTimeout(() => {
uni.showModal({
title: '取号成功',
content: res.result.getJSON("res")?.getString("phoneNumber"),
showCancel: false
});
}, 100);
}).catch(err => {
console.error(JSON.stringify(err));
// 关闭登录页
this.univerifyManager?.close();
setTimeout(() => {
uni.showModal({
title: '取号失败',
content: (err as Error).message,
showCancel: false
});
}, 100);
});
}
}
}
</script>
<style>
</style>/style>
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
errMsg | string | 是 | - | 错误信息 |