# uni.getUniverifyManager()

获取一键登录管理对象

App一键登陆,封装了个推的一键登陆sdk,其内部再次封装了中国三大电信运营商提供的sdk。通过运营商提供的服务,可以在手机sim卡信号正常的情况下,通过云端接口获取到当前用户的手机号。

App一键登陆是替代短信验证码登录的更优选择:对开发者而言更便宜、对用户而言体验更好。

一键登陆涉及业务开通和付费,涉及客户端和服务器交互,有较多文档:

  1. 业务介绍:介绍业务流程、开通和付费。详见
  2. 客户端API,即本文
  3. 服务器API,详见

uni-id-pages,已经内置一键登陆,从云端到客户端均已开发好并开源,推荐使用。详情

# 返回值

类型
UniverifyManager

# UniverifyManager 的方法

# preLogin(options)

预登录

# 参数
名称 类型 必填 默认值 描述
options PreLoginOptions - 预登录参数
名称 类型 必备 默认值 描述
success () => void - -
fail (err: PreLoginFail) => void - -
complete (res: any) => void - -
# PreLoginFail 的属性值
名称 类型 必备 默认值 描述
errCode 1000 | 1001 | 1002 | 1004 | 4001 | 30004 | 30005 | 30006 - 1000 当前应用appid尚未开通uni一键登录
1001 应用所有者账号信息异常,请检查账号一键登录服务是否正常
1002 应用所有者账号信息异常,请检查账号余额是否充足
1004 uni一键登录应用不存在
4001 参数异常
30004 其他错误
30005 预登录失败
30006 一键登录失败
errSubject string - 统一错误主题(模块)名称
data any | null - 错误信息中包含的数据
cause Error | null - 源错误信息,可以包含多个错误,详见SourceError
errMsg string - -
# preLogin 兼容性
Android iOS web
3.99 x -

# login(options)

登录

# 参数
名称 类型 必填 默认值 描述
options LoginOptions - 登录参数
名称 类型 必备 默认值 描述
univerifyStyle UniverifyStyle - 登录页样式
名称 类型 必备 默认值 描述
fullScreen boolean - 是否全屏
logoPath string - logo路径
backgroundColor string - 登录页背景色
loginBtnText string - 登录按钮文字
success (res: LoginSuccess) => void - -
fail (err: LoginFail) => void - -
complete (res: any) => void - -
# LoginSuccess 的属性值
名称 类型 必备 默认值 描述
openId string - 登录授权唯一标识
accessToken string - token
# LoginFail 的属性值
名称 类型 必备 默认值 描述
errCode 1000 | 1001 | 1002 | 1004 | 4001 | 30004 | 30005 | 30006 - 1000 当前应用appid尚未开通uni一键登录
1001 应用所有者账号信息异常,请检查账号一键登录服务是否正常
1002 应用所有者账号信息异常,请检查账号余额是否充足
1004 uni一键登录应用不存在
4001 参数异常
30004 其他错误
30005 预登录失败
30006 一键登录失败
errSubject string - 统一错误主题(模块)名称
data any | null - 错误信息中包含的数据
cause Error | null - 源错误信息,可以包含多个错误,详见SourceError
errMsg string - -
# login 兼容性
Android iOS web
3.99 x -

# close()

关闭登录页

# close 兼容性
Android iOS web
3.99 x -

# isPreLoginValid()

预登录是否有效

# 返回值
类型
boolean
# isPreLoginValid 兼容性
Android iOS web
3.99 x -

# getUniverifyManager 兼容性

Android iOS web
3.99 x -

# 参见

相关 Bug

# cause个推sdk错误码及运营商错误码汇总

上述API不管是预登陆还是登录,失败时返回的uni Error错误对象,有一个属性cause,它表示底层的错误来源,这里包含了个推的个验sdk和运营商sdk的详细信息。比如没有sim卡或未开启蜂窝网络。

在大多数情况下,开发者需要把这些更为详细的错误提示给用户,以引导用户正确使用一键登陆。

# 个推sdk错误码

错误码 错误信息
-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切换超时

# Tips

  • 运营商对一键登陆给用户呈现的ui有强制要求:必须有运营商的隐私协议和服务条款、不得默认勾选同意、手机号掩码显示、需要用户手动再点按钮获取而不能自动获取。
  • 目前一键登陆的UI可自定义性有限。仅支持配置登录页全屏/半屏、登录页背景色、登录按钮文案以及登录页logo。后续会继续扩展自定义性。
  • 一键登陆并非100%成功,手机没有sim卡和蜂窝网络未开启是最常见的原因,更多错误见上方的错误码列表。在一键登陆无法使用时,可转为短信验证码登录。在uni-id-pages里已经集成了相关逻辑,无需自己开发。详情
  • 一键登陆支持标准基座真机运行,涉及费用扣除开发者的费用。无需自定义基座。

# 示例

hello uni-app x

<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="primary" @click="verify(false)">一键登录(半屏)</button>
     </view>
     <view class="uni-btn-v uni-common-mt">
       <button type="primary" @click="verify(true)">一键登录(全屏)</button>
     </view>
   </view>
 </view>
</template>

<script>
 export default {
   data() {
     return {
       title: '一键登录',
       univerifyManager: null as UniverifyManager | null
     }
   },
   onLoad() {
     this.univerifyManager = uni.getUniverifyManager();
     // 预登录
     this.univerifyManager?.preLogin({
       success: () => {
         console.log("pre login success");
       },
       fail: (err : PreLoginFail) => {
         console.error("pre login fail => " + JSON.stringify(err));
         uni.showModal({
           title: '预登录失败',
           content: JSON.parseObject(err.cause?.cause?.message ?? "")?.getString("errorDesc") ?? err.errMsg,
           showCancel: false
         });
       }
     } as PreLoginOptions);
   },
   methods: {
     verify(fullScreen : boolean) {
       // 校验预登录是否有效
       const isPreLoginValid = this.univerifyManager?.isPreLoginValid() ?? false;
       if (isPreLoginValid) {
         // 预登录有效,执行登录
         this.login(fullScreen);
       } else {
         // 预登录无效,执行预登录
         this.univerifyManager?.preLogin({
           success: () => {
             console.log("pre login success");
             this.login(fullScreen);
           },
           fail: (err : PreLoginFail) => {
             console.error("pre login fail => " + JSON.stringify(err));
             uni.showModal({
               title: '预登录失败',
               content: JSON.parseObject(err.cause?.cause?.message ?? "")?.getString("errorDesc") ?? err.errMsg,
               showCancel: false
             });
           }
         } as PreLoginOptions);
       }
     },
     login(fullScreen : boolean) {
       this.univerifyManager?.login({
         // 登录页样式
         univerifyStyle: {
           fullScreen: fullScreen,
           backgroundColor: "#FFFFFF",
           loginBtnText: "一键登录",
           logoPath: "/static/logo.png"
         } as UniverifyStyle,
         success: (res : LoginSuccess) => {
           console.log("login success => " + JSON.stringify(res));
           // 云函数取号
           uniCloud.callFunction({
             name: 'univerify',
             data: {
               access_token: res.accessToken, // 客户端一键登录接口返回的access_token
               openid: res.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);
           });
         },
         fail: (err : LoginFail) => {
           console.error("login fail => " + err);
           uni.showModal({
             title: '登录失败',
             content: JSON.parseObject(err.cause?.cause?.message ?? "")?.getString("errorDesc") ?? err.errMsg,
             showCancel: false
           });
         }
       } as LoginOptions);
     }
   }
 }
</script>

<style>

</style>

# 通用类型

# GeneralCallbackResult

名称 类型 必备 默认值 描述
errMsg string - 错误信息