# One-click login

univerify is a one-click login product launched by DCloud. Through in-depth cooperation with operators, APP users can automatically log in with their mobile phone numbers without entering account passwords.

univerify is a next-generation login verification method that replaces SMS verification login. It can eliminate the pain points of the existing SMS verification mode, such as long waiting time, cumbersome operation, and easy leakage.

Note: One-click login must be based on the premise of using mobile data to obtain the mobile phone number. The mobile phone number cannot be obtained when connecting to the Wi-Fi network. At the same time, if it is a dual-card mobile phone, the obtained mobile phone number is the one with the default mobile data SIM card number.

# Important adjustments

# Cloud function uses one-click login extension library

Since HBuilderX 3.4.0, one-click login related functions have been moved to the extension library uni-cloud-verify. For a period of time, regardless of whether the developer uses the extension library cloud function, uniCloud.getPhoneNumber can be used normally. HBuilderX 3.4.0 and later versions cannot call the uniCloud.getPhoneNumber interface if the cloud function that uses the uni-cloud-verify extension library is not specified when uploading the cloud function.

For instructions on the extension library, see: Cloud function extension library

Add the reference of uni-cloud-verify in the package.json of the cloud function to enable this extension for the cloud function without any other adjustments. The complete package.json example is as follows:

{
	"name": "univerify",
	"extensions": {
		"uni-cloud-verify": {} // 启用一键登录扩展,值为空对象即可
	}
}

# client

Please refer to this document for how to use one-click login on the client side: univerify User Guide

# cloud function

Since HBuilderX 3.4.0, the cloud function needs to enable uni-cloud-verify before calling the getPhoneNumber interface. For details, see:Cloud function uses one-key login extension library

When the client calls the one-click login interface, the following results will be obtained

{  
    "target": {  
        "id": "univerify",  
        "description": "一键登录",  
        "authResult": {  
            "openid": "xxx",  
            "access_token": "xxx"  
        }  
    }  
}  

Use the openid and access_token in the above results to call the interface in the cloud function to obtain the mobile phone number

The interface call form of the cloud function is as follows

exports.main = async function(event, context){
  const res = await uniCloud.getPhoneNumber({
    provider: 'univerify',
    appid: context.APPID, // 客户端callFunction时携带的AppId信息
    apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
    apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
    access_token: event.access_token,
    openid: event.openid
  })
  // {
  //   code: 0,
  //   message: '',
  //   phoneNumber: '138xxxxxxxx'
  // }
}

Related documents

# uni-app项目

If you develop a uni-app project, you can use callFunction to call cloud functions

// client
uniCloud.callFunction({
  name: 'xxx', // 你的云函数名称
  data: {
    access_token: 'xxx', // 客户端一键登录接口返回的access_token
    openid: 'xxx' // 客户端一键登录接口返回的openid
  }
}).then(res => {
  // res.result = {
  //   code: '',
  //   message: ''
  // }
}).catch(err=>{
  // handle errors
})

// cloud function
exports.main = async function (event, context){
  const res = await uniCloud.getPhoneNumber({
    appid: context.APPID, // 客户端callFunction时携带的AppId信息
  	provider: 'univerify',
  	apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
  	apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
  	access_token: event.access_token,
  	openid: event.openid
  })
  // Perform operations such as warehousing. Under normal circumstances, do not return the complete mobile phone number to the front end
  return {
    code: 0,
    message: '获取手机号成功'
  }
}

Notice

  • If the appid is reacquired during development, the uni-app project needs to be recompiled

# 5+ items

5+ projects cannot use callFunction to request cloud functions. At this time, cloud function URLs can be used to allow 5+ projects to access cloud functions through http requests.

// client
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, the following only shows the scenario where the client uses the post method to send a request with content-type application/json
exports.main = async function(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
    apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
    apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
    access_token: access_token,
    openid: openid
  })
  // Perform operations such as warehousing. Under normal circumstances, do not return the complete mobile phone number to the front end
  return {
    code: 0,
    message: '获取手机号成功'
  }
}

# own server call

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 legal

// Take nodejs as an example
const crypto = require('crypto')

const secret = 'your-secret-string' // 自己的密钥不要直接使用示例值,且注意不要泄露
const hmac = crypto.createHmac('sha256', secret);

// Self-owned server generates a signature and sends the request in GET mode
const params = {
  access_token: 'xxx', // 客户端传到自己服务器的参数
  openid: 'xxx'
}
// concatenate the signature string after alphabetical sorting
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 the following link, where https://xxxx/xxx is the Url address 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 the GET request is taken as an example for demonstration
const crypto = require('crypto')
exports.main = async function (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
  	apiKey: 'xxx', // 在开发者中心开通服务并获取apiKey
  	apiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecret
  	access_token: access_token,
  	openid: openid
  })
  // Return the phone number to the own server
  return res
}

# One-click login fee description

  • 0.02 yuan/time, failure will not be charged.

In actual use, you need to rely on the uniCloud cloud service, and the costs are as follows: After using the official version of Alibaba Cloud, each one-click login request will consume about 0.0000139 yuan in uniCloud, which is almost negligible. It can also be roughly considered that the cost of using one-key login every time is 0.0200139 yuan/time. The fee calculation rules are as follows:

The part of the one-click login business that involves expenses is mainly the usage of cloud functions/cloud objects, the number of calls, and the outbound traffic (for example: using a custom cloud function/cloud object to obtain a mobile phone number). Next, we conduct cost assessments for different resources.

According to the pay-as-you-go rules listed on the uniCloud official website, we can simply get the following formula:

Cloud function/cloud object cost = resource usage * 0.000110592 + number of calls * 0.0133 / 10000 + outbound traffic * 0.8

in:

  • Resource usage = cloud function memory (in G) * average execution time of a cloud function (in seconds) * number of calls
  • Number of calls = number of one-click login calls

We assume the following data model:

  • Cloud function memory: 512M, which is 0.5G (the cloud function memory is 512M by default, and the user can customize the setting, and the minimum can be set to 128M. If you only use one-key login and no other complicated business, then the memory can be set to 128M for further reduced cost of
  • The average execution time of a cloud function: 200 milliseconds, or 0.2 seconds
  • One-click login service average daily calls: 10,000 times
  • Outbound traffic: 2 KB for a single request

According to the above formula, the daily cost of the one-click login business cloud function is:

云函数费用(天) = 资源使用量 * 0.000110592  + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
			  = 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
			  = 0.5G * 0.2S * 10000 * 0.000110592 + 10000 * 0.0133/10000 + 10000 * 2 * 0.8 / (1024 * 1024) 
			  = 0.110592 + 0.0133 + 0.0152587890625
			  = 0.1391507890625(元)
			  ≈ 0.139(元)

Conclusion: If your "one-click login" business obtains mobile phone numbers 10,000 times on average per day, after using the official cloud service space of Alibaba Cloud, the corresponding cloud function will consume about 0.139 yuan per day. Compared with the previous one-click login fee, the average per Each call costs 0.0000139 yuan more, which is almost negligible.

Obviously, one-click login is a cheaper user authentication method than SMS verification codes.