English
uni one-click login
is a service launched by DCloud and a push company that integrates the gateway authentication capabilities of the three major operators.
Through the operator's underlying SDK, the App can directly obtain the mobile phone number without SMS verification code, which is the one-click login function provided by many mainstream apps.
uni one-click login
is a next-generation login verification method that replaces SMS verification login, which can eliminate the pain points of long waiting time, cumbersome operation and easy leakage of the existing SMS verification mode.
HBuilderX3.1.6+ version authorization login interface supports full screen mode
When calling uni.login, set the fullScreen property value in unverifyStyle to true:
uni.login({
provider: 'univerify',
univerifyStyle: {
fullScreen: true
}
})
The full screen effect is as follows:
One-click login, no need to wait and copy SMS verification codes, can effectively reduce the user churn rate and improve the conversion rate of user registrations in app activations.
Use uni one-click login
, each verification only takes 2 points! It is several times cheaper than the SMS verification code, and it is also cheaper than the one-click login provided by the three parties on the market.
Adopt operator gateway authentication to avoid SMS hijacking and effectively improve security
There is no need for native plug-ins or custom bases (the HBuilder standard base can run and debug directly), and it is simple and fast to go online.
access_token
and other information.access_token
and other information with the real mobile phone number of the current device. Then the server is directly stored in the warehouse to avoid the untrustworthy situation that the mobile phone number is passed to the front end.precondition:
开发者需要登录uniCloud控制台,申请开通一键登录服务。
详细步骤参考:一键登录服务开通指南
Notice
After the application has opened the uni one-click login service, it needs to wait for the approval before it can be officially used. During the review period, you can use the HBuilder standard base to run the one-key login function, and the fee will be deducted from your account when you call it; but during the review period, you cannot use the custom base to call the one-key login function, and the call will return mistake.
One-click login After obtaining access_token
on the client side, you must exchange your mobile phone number at uniCloud.
After getting the phone number in the cloud function of uniCloud, you can use it directly, or transfer it to a traditional server for processing, or you can use the cloud function url method Generate a common http interface for 5+ apps to use.
Notice: Although one-click login requires uniCloud, it does not require developers to migrate all background services to uniCloud
服务器API详见:uniCloud云函数中使用一键登录
uniCloud产生的费用对于一键登陆可以忽略,详见
This article mainly introduces the client calling method of uni-app. For 5+ App (Wap2App), please refer to: 5+ App One-Key Login User Guide
DCloud还提供了更易用的封装。在uni-id里已经预置了uni一键登录
,并基于uni-id
提供了云端一体应用快速开发基本项目模版,该项目模版内置了包括一键登录在内的各种常用登录示例,开发者可以拿去直接用
Next, continue to introduce the usage of the original API.
One-click login is parallel to providers such as WeChat login and QQ login in uni.login.
The provider ID corresponding to one-click login is 'univerify'. When the provider list is obtained and found to contain 'univerify', it means that the current environment has packaged the one-click login SDK.
uni.getProvider({
service: 'oauth',
success: function (res) {
console.log(res.provider)// ['qq', 'univerify']
}
});
The pre-login operation can determine whether the current device environment supports one-key login. If one-key login is supported, the one-key login option can be displayed at this time. At the same time, the pre-login will prepare the relevant environment, which significantly improves the speed of displaying the authorized login interface.
If the current device environment does not support one-click login, other login options should be displayed at this time.
If a valid SIM card is not inserted into the phone, or the cellular data network of the phone is turned off, the pre-login verification may fail.
uni.preLogin(options)
uni.preLogin({
provider: 'univerify',
success(){ //预登录成功
// Display one-click login options
},
fail(res){ // 预登录失败
// Don't show the one-click login option (or grey it out)
// Determine the cause of the failure according to the error message, and submit the error to the statistics server if necessary
console.log(res.errCode)
console.log(res.errMsg)
}
})
The user authorization interface pops up. Return the corresponding callback according to the user operation and authorization result, and get the access_token
uni.login(options);
uni.login({
provider: 'univerify',
univerifyStyle: { // 自定义登录框样式
//Refer to `univerifyStyle data structure`
},
success(res){ // 登录成功
console.log(res.authResult); // {openid:'登录授权唯一标识',access_token:'接口返回的 token'}
},
fail(res){ // 登录失败
console.log(res.errCode)
console.log(res.errMsg)
}
})
The authorization pop-up interface of uni one-click login
is half-screen by default, and can also be configured to be full-screen. This interface is essentially popped up by the operator's sdk, which asks the mobile phone user whether to authorize their mobile phone number to be used by the app.
This authorization popup interface can be limitedly customized via the unverifyStyle setting.
unverifyStyle data structure:
{
"fullScreen": false, // 是否全屏显示,默认值: false
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)
"icon": {
"path": "static/xxx.png", // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
"width": "60px", //图标宽度 默认值:60px
"height": "60px" //图标高度 默认值:60px
},
"closeIcon": {
"path": "static/xxx.png", // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
"width": "60px", //图标宽度 默认值:60px (HBuilderX 4.0支持)
"height": "60px" //图标高度 默认值:60px (HBuilderX 4.0支持)
},
"phoneNum": {
"color": "#202020" // 手机号文字颜色 默认值:#202020
},
"slogan": {
"color": "#BBBBBB" // slogan 字体颜色 默认值:#BBBBBB
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”
"borderRadius": "24px" // 授权按钮圆角 默认值:"24px" (按钮高度的一半)
},
"otherLoginButton": {
"visible": true, // 是否显示其他登录按钮,默认值:true
"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderColor": "", //边框颜色 默认值:透明(仅iOS支持)
"borderRadius": "0px" // 其他登录按钮圆角 默认值:"24px" (按钮高度的一半)
},
"privacyTerms": {
"defaultCheckBoxState":true, // 条款勾选框初始状态 默认值: true
"isCenterHint":false, //未勾选服务条款时点击登录按钮的提示是否居中显示 默认值: false (3.7.13+ 版本支持)
"uncheckedImage":"", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)
"checkedImage":"", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)
"checkBoxSize":12, // 可选 条款勾选框大小
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": [ // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
},
"buttons": { // 自定义页面下方按钮仅全屏模式生效(3.1.14+ 版本支持)
"iconWidth": "45px", // 图标宽度(高度等比例缩放) 默认值:45px
"list": [
{
"provider": "apple",
"iconPath": "/static/apple.png" // 图标路径仅支持本地图片
},
{
"provider": "weixin",
"iconPath": "/static/wechat.png" // 图标路径仅支持本地图片
}
]
}
}
The interface indication diagram corresponding to the configuration of the unverifyStyle property
Full screen effect | Non full screen effect |
---|---|
Return data example
{
"errMsg": "login:ok",
"authResult": {
"openid": "208E2FBE6EF64DF3B2D377D886EF2A14124262bfd7ae16465ea0f0634554dcee7636",
"access_token": "ZGI4NjkxZWE4YjAyNGUzMjhiMmZiNDcwODBjYjc5MDF8fDJ8djJ8Mg=="
}
}
After the request for login authentication is completed, the one-key login interface will not be closed regardless of success or failure. You need to actively call the closeAuthView
method to close it.
The completion of the client login authentication only means that the access_token
is obtained successfully. You need to submit this data to the server to obtain the mobile phone number. After completing the business service login logic, notify the client to close the login interface.
uni.closeAuthView()
If the "fullScreen": "true"
and buttons
options are configured in univerifyStyle
and the buttons
array is not empty, custom buttons will be rendered in full screen.
When the user clicks the custom button
, the fail
callback of uni.login
is triggered, and the returned data is as follows:
{
"code": "30008",
"errMsg": "用户点击了自定义按钮",
"index": 0, // 第几个按钮
"provider": "apple",
}
uni.getCheckBoxState(options)
uni.getCheckBoxState({
success(res){
console.log(res.state) // Boolean 用户是否勾选了选框
console.log(res.errMsg)
},
fail(res){
console.log(res.errCode)
console.log(res.errMsg)
}
})
3.2.13+ version can use the global univerifyManager to use one-click login more efficiently
At this point, clicking the custom button will not trigger the
fail
callback ofuni.login
, nor will it automatically close the one-click login popup
const univerifyManager = uni.getUniverifyManager()
// pre-login
univerifyManager.preLogin()
// Call the one-click login popup
univerifyManager.login({
univerifyStyle: {
"fullScreen": true,
"buttons": {
"iconWidth": "45px",
"list": [
{
"provider": "apple",
"iconPath": "/static/apple.png"
},
{
"provider": "weixin",
"iconPath": "/static/wechat.png"
}
]
}
},
success (res) {
console.log('login success', res)
}
})
const callback = (res) => {
// Get the check status of the one-click login popup protocol
univerifyManager.getCheckBoxState({
success(res) {
console.log("getCheckBoxState res: ", res);
if (res.state) {
// Close the one-click login popup
univerifyManager.close()
}
}
})
}
// Subscribe to custom button click event
univerifyManager.onButtonsClick(callback)
// Unsubscribe from custom button click event
univerifyManager.offButtonsClick(callback)
After the client obtains the access_token
, it passes it to the uniCloud cloud function, and the cloud function obtains the real phone number through the uniCloud.getPhoneNumber
method.
There are 3 ways to do this step:
uniCloud.callFunction
in the front end, and pass the access_token
to the specified cloud function.access_token
to the cloud function of uniCloud using a normal ajax request. This method can be used for uni-app, 5+App, and wap2app, but the cloud function on uniCloud needs to be URLized.access_token
to your traditional server using a normal ajax request, and then forward it to the uniCloud cloud function through your own traditional server. This method can be used for uni-app, 5+App, and wap2app, but the cloud function on uniCloud needs to be URLized.Sample codes are provided below:
If it is a uni-app project that has not been opened through uniCloud:
Client example:
// After getting access_token, call cloud function through callfunction
uniCloud.callFunction({
name: 'xxx', // 你的云函数名称
data: {
'access_token': 'xxx', // 客户端一键登录接口返回的access_token
'openid': 'xxx' // 客户端一键登录接口返回的openid
}
}).then(res => {
// res.result = {
// code: '',
// message: ''
// }
// The login is successful, you can close the one-click login authorization interface
}).catch(err=>{
// handle errors
})
Cloud function code example:
'use strict';
exports.main = async (event, context) => {
// event contains the parameters submitted by the client
const res = await uniCloud.getPhoneNumber({
appid: '_UNI_ABCDEFG', // 替换成自己开通一键登录的应用的DCloud appid
provider: 'univerify',
access_token: event.access_token,
openid: event.openid
})
console.log(res); // res里包含手机号
// Perform operations such as user information storage. Under normal circumstances, do not return the full mobile phone number to the front end
// 如果数据库在uniCloud上,可以直接入库
// 如果数据库不在uniCloud上,可以通过 uniCloud.httpclient API,将手机号通过http方式传递给其他服务器的接口,详见:https://doc.dcloud.net.cn/uniCloud/cf-functions?id=httpclient
return {
code: 0,
message: '获取手机号成功'
}
}
For the complete source code of the project example, please refer to:
Notice
5+ (wap2app) projects cannot use uniCloud.callFunction to request cloud functions.
The uniCloud cloud function provides the URLization solution, which can expose the cloud function to a common http interface. Setting method reference: https://uniapp.dcloud.io/uniCloud/http
At this time, the client code uses ordinary ajax writing.
Client code:
const xhr = new plus.net.XMLHttpRequest();
xhr.onload = function(e) {
const {
code,
message
} = JSON.parse(xhr.responseText)
}
xhr.open( "POST", "https://xxx" ); // url应为云函数Url化之后的地址,可以在uniCloud web控制台云函数详情页面看到
xhr.setRequestHeader('Content-Type','application/json');
xhr.send(JSON.stringify({
access_token: 'xxx', // 客户端一键登录接口返回的access_token
openid: 'xxx' // 客户端一键登录接口返回的openid
}));
Cloud function code:
// The following only shows the scenario where the client sends a request with a content-type of application/json using the post method
exports.main = async(event) => {
let body = event.body
if(event.isBase64Encoded) {
body = Buffer.from(body,'base64')
}
const {
access_token,
openid
} = JSON.parse(body)
const res = await uniCloud.getPhoneNumber({
provider: 'univerify',
appid: 'xxx', // DCloud appid,不同于callFunction方式调用,使用云函数Url化需要传递DCloud appid参数!!!
access_token: access_token,
openid: openid
})
console.log(res); // res里包含手机号
// 如果数据库不在uniCloud上,可以通过 uniCloud.httpclient API,将手机号通过http方式传递给其他服务器的接口,详见:https://doc.dcloud.net.cn/uniCloud/cf-functions?id=httpclient
return { // 不建议把完整手机号返回给前端
code: 0,
message: '获取手机号成功'
}
}
The uni-app project can also use ordinary uni.request to request the URLized http interface of the cloud function, and the example will not be repeated here.
Developers can also pass information such as access_token to their traditional servers after the client obtains them. Then use your own traditional server to access the cloud function of uniCloud (the cloud function needs to be URLized).
The writing method is similar to the urlization method of the cloud function of the above 5+ projects, but the difference is that the cloud function needs to return the mobile phone number to its own server, so that data security needs to be ensured.
The following is a simple example to demonstrate how to use the signature to verify whether the request is legitimate
// Take nodejs as an example
const crypto = require('crypto')
const secret = 'your-secret-string' // 自己的密钥不要直接使用示例值,且注意不要泄露
const hmac = crypto.createHmac('sha256', secret);
// Generate signature by own server and send request in GET mode
const params = {
access_token: 'xxx', // 客户端传到自己服务器的参数
openid: 'xxx'
}
// Concatenate the signature string after sorting alphabetically
const signStr = Object.keys(params).sort().map(key => {
return `${key}=${params[key]}`
}).join('&')
hmac.update(signStr);
const sign = hmac.digest('hex')
// The final request is as follows, where https://xxxx/xxx is the URL of the cloud function
// https://xxxx/xxx?access_token=xxx&openid=xxx&sign=${sign} where ${sign} is the sign value obtained in the previous step
// The cloud function verifies the signature. In this example, accepting a GET request is used as an example to demonstrate
const crypto = require('crypto')
exports.main = async(event) => {
const secret = 'your-secret-string' // 自己的密钥不要直接使用示例值,且注意不要泄露
const hmac = crypto.createHmac('sha256', secret);
let params = event.queryStringParameters
const sign = params.sign
delete params.sign
const signStr = Object.keys(params).sort().map(key => {
return `${key}=${params[key]}`
}).join('&')
hmac.update(signStr);
if(sign!==hmac.digest('hex')){
throw new Error('非法访问')
}
const {
access_token,
openid
} = params
const res = await uniCloud.getPhoneNumber({
provider: 'univerify',
appid: 'xxx', // DCloud appid,不同于callFunction方式调用,使用云函数Url化需要传递DCloud appid参数
access_token: access_token,
openid: openid
})
// Return the phone number to the server
return res
}
{
"data": {
"code": 0,
"success": true,
"phoneNumber": "166xxxx6666"
},
"statusCode": 200,
"header": {
"Content-Type": "application/json; charset=utf-8",
"Connection": "keep-alive",
"Content-Length": "53",
"Date": "Fri, 06 Nov 2020 08:57:21 GMT",
"X-CloudBase-Request-Id": "xxxxxxxxxxx",
"ETag": "xxxxxx"
},
"errMsg": "request:ok"
}
Error code | Error description | Solution |
---|---|---|
-7 | uniAppid is missing | check if configured/approved |
1000 | The current uniAppid has not yet opened one-key login | Check whether it is configured/passed audit |
1001 | The account information of the application owner is abnormal, please check whether the one-click login service of the account is normal | Check whether the one-click login service of the account is normal |
1002 | The account information of the application owner is abnormal, please check whether the account balance is sufficient | Check whether the account balance is sufficient |
4001 | The request parameter is abnormal | The verification is abnormal, contact the official staff |
4003 | 开发者账户appid 校验异常,联系官方人员 | 校验异常,联系官方人员 |
5000 | 取号失败,请检查SIM卡是否停机欠费;token是否过期 | 联系官方人员 |
20202 | Terminal does not enable SIM data | Guide users to manually turn on device data |
30001 | The current network environment is not suitable for this operation | None |
30002 | User clicked on another login method | None |
30003 | 用户关闭验证界面 | 无 |
30004 | 其他错误 | 30004章节自查或联系官方人员 |
30005 | Pre-login failed | There is no prerequisite for one-key login, the device does not support / data traffic is not enabled / other reasons |
30006 | One-click login failed | None |
30007 | Failed to obtain the verification token of the local number | The verification is abnormal, contact the official staff |
30008 | User clicked custom button | None |
40004 | The application does not exist | It is often used in custom docking scenarios, please ensure that the application has been reviewed and repackaged |
40047 | One-key login failed to get number | Check abnormal, contact official staff |
40053 | The mobile phone number verification failed | The verification is abnormal, contact the official staff |
40101 | Mobile-source IP authentication failed | Check whether the mobile phone card type is a normal carrier mobile phone card, and try again after turning off the airplane mode. |
40201 | Unicom-source IP authentication failed | Check whether the mobile phone card type is a normal carrier mobile phone card, and try again after turning off the airplane mode. |
40301 | Telecom - source IP authentication failed | Check whether the mobile phone card type is a normal carrier mobile phone card, and try again after turning off the airplane mode. |
使用uni一键登录
,安卓平台不需要制作自定义基座,使用HBuilder标准真机运行基座即可,调用时会从你的账户中扣费。iOS平台使用标准基座必须要用io.dcloud.HBuilder
这个bundleId重签,其他bundleId重签无法登录。
Cloud packaging
Offline packaging
Pre-login validity period The pre-login is valid for 10 minutes. After 10 minutes, the pre-login is invalid. At this time, calling the login authorization login is equivalent to not calling the pre-login before. It takes about 1-2 seconds before the authorization interface pops up. Pre-login can only be used once. After calling login to pop up the authorization interface, if the user cancels the login authorization, the pre-login needs to be called again when using one-key login again.
Can dual SIM phones get two phone numbers at the same time It is not supported to obtain two mobile phone numbers at the same time. Dual SIM phones are authenticated with a SIM card with data traffic turned on.
Prompt "Non-Mobile Gateway IP Address" In most cases, it is because some specific devices do not support dual-card dual-standby network environment.
uniCloud费用贵不贵? uniCloud产生的费用对于一键登陆可以忽略,详见
Other questions about use
欢迎扫码加入 一键登录 微信交流群讨论: