uniapp app 阿里云一键登录功能实现

一键登录功能

官网文档 https://uniapp.dcloud.net.cn/uniCloud/univerify.html#univerify
univerify 是DCloud 推出的一键登录产品,通过与运营商深度合作,实现APP用户无需输入帐号密码,即可使用本机手机号码自动登录的能力。
注意:一键登录必须是手机使用流量的前提下才能获取到手机号码,用Wi-Fi联网时无法获取到手机号码,同时如果是双卡手机,获取到的手机号码是默认移动数据的那个手机卡的号码。

uni-app账号准备

1、uni-app官网注册账号,并且在DCloud开发者中心创建应用
2、开通一键登录服务 保管好ApiKey 和 ApiSecret


ApiKey.png

3、点击上图基础配置页面右下角添加应用(开通一键登录服务的应用)


添加开启一键登录服务的应用.jpg

开始踩坑了
坑一:关于如何获取Android应用签名MD5和SHA256,需要安装jre环境,新版JRE环境下已不支持生成MD5,具体操作可参考https://ask.dcloud.net.cn/article/35777,自己电脑中装了新版只拿到了SHA256,MD5半天没弄好,嫌麻烦,随便找了一个,也能用,后面公司开发项目的时候,这两个签名需要问公司要哦;

4、添加服务空间


安全配置.png

uni-app 开通一键登录服务

1、项目开通uniCloud 服务

关联云空间选择阿里云或者腾讯云都可以,这里选择阿里云;

项目关联云空间.jpg

2、新建云函数


新建云函数.jpg

3、新建云函数后会有一个index.js生成,粘贴一下代码

    'use strict';
    const crypto = require('crypto')
    exports.main = async (event, context) => {
        //event为客户端上传的参数
        console.log('event : ', event,5);
        console.log('参数', event.queryStringParameters);
        // event里包含着客户端提交的参数
        const res = await uniCloud.getPhoneNumber({
            appid: '__UNI__FF1F966', // 替换成自己开通一键登录的应用的DCloud appid,使用callFunction方式调用时可以不传(会自动取当前客户端的appid),如果使用云函数URL化的方式访问必须传此参数
            provider: 'univerify',
            apiKey: '84d1e1cf1730cb52870d5df100501226', // 在开发者中心开通服务并获取apiKey
            apiSecret: '26f1c69122a10ad0e103e5e7a157a407', // 在开发者中心开通服务并获取apiSecret
            access_token: event.access_token,
            openid: event.openid
        })
        console.log('res',res); // res里包含手机号
        // 执行用户信息入库等操作,正常情况下不要把完整手机号返回给前端
        // 如果数据库在uniCloud上,可以直接入库
        // 如果数据库不在uniCloud上,可以通过 uniCloud.httpclient API,将手机号通过http方式传递给其他服务器的接口,详见:https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=httpclient
        
        return {
            code: 0,
            message: '获取手机号成功',
            data: res
        }
    };

坑二:
云函数中event参数中的access_token和openid 直接使用event.access_token,event.openid,使用event.queryStringParameters.access_token,
event.queryStringParameters.openid 会报错;

4、保存后上传部署到云空间


上传部署云函数.jpg

5、勾选项目中一键登录(项目中manifest.json)


manifest勾选.jpg

项目编辑

1、项目中新建common文件夹并且新建my_serve.js文件,创建预登录以及一键快速登录函数,并且导出

export default {   
    /**     * 一键登录预登录检查     * @return {boolean} 是否支持一键登录       */    
    pre_login(){        
        uni.getProvider({ 
            //获取可用的服务提供商            
            service: 'oauth',            
            success: function(res) {                
                console.log(res.provider) // ['weixin', qq', 'univerify']           
                },
            });        
            return new Promise((resolve, reject)=>{            
                uni.preLogin({ 
                    //预登录                
                    provider: 'univerify', //用手机号登录                
                    success() {   
                        console.log('预登录成功,16')
                        resolve(true)                
                        },                
                    fail(err) { 
                        //预登录失败                    
                        console.log(`预登录失败(${err.errCode})`, err.errMsg)                    
                        resolve(false)                
                        }           
                    })       
                })    
            },   
             /**  * 本机号码一键登录     */    
             async fast_login(){        
                 return new Promise((resolve, reject)=>{            
                     uni.login({ 
                     //正式登录,弹出授权窗                
                     provider: 'univerify',                
                     univerifyStyle: { 
                         // 自定义登录框样式                    
                         "fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。                    
                         "backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff                    
                          "phoneNum": {                        
                              "color": "#000000", // 手机号文字颜色 默认值:#000000                       
                              },                    
                          "authButton": {                        
                              "normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5                          
                              "highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)                          
                              "disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持) 
                              "textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff                          
                              "title": "本机号码一键登录" ,// 授权按钮文案 默认值:“本机号码一键登录”                     
                              },
                              "buttons": {
                                  "iconWidth": "30px",
                                  "list": [
                                      {
                                          "provider": "sinaweibo",
                                          "iconPath": "/static/sina.png"
                                      }, 
                                      {
                                          "provider": "weixin",
                                             "iconPath": "/static/wechat.png"
                                      }, 
                                      {
                                          "provider": "qq",
                                             "iconPath": "/static/qq.png"
                                      }
                                     ]
                                  },
                            },               
                         success(res) { 
                             // 正式登录成功  
                             console.log(111)
                             console.log(res.authResult,50); 
                            //  {
                            //   openid:'登录授权唯一标识',
                            //   access_token:'接口返回的 token'
                            // }                    
                          resolve(res.authResult) 
                          // 在得到access_token后,通过callfunction调用云函数              
                           uniCloud.callFunction({                   
                                   name: 'oneLogin', // 云函数名称                    
                                   data: { //传给云函数的参数                    
                                   'access_token': res.authResult.access_token, //客户端一键登录接口返回的access_token                    
                                   'openid': res.authResult.openid // 客户端一键登录接口返回的openid                    
                                   },                   
                                   success(callRes) {                   
                                       console.log('调用云函数成功' + callRes + '获取手机号成功')
                                       uni.navigateTo({
                                        url:"/pages/my/my"
                                       }) 
                                                        
                                   },                   
                                   fail(callErr) {                
                                       console.log('调用云函数出错' + callErr)                 
                                   },                  
                                   complete() {                  
                                       uni.closeAuthView() //关闭授权登录界面                   
                                   }                    
                               })                    
                            uni.closeAuthView() //关闭授权登录界面               
                        },                
                        fail(err) { 
                        // 正式登录失败                    
                        console.log(`一键登录失败(${err.errCode})`, err.errMsg)                    
                        reject(err)                    
                        // uni.closeAuthView() 
                        //关闭授权登录界面              
                         }           
                    })       
                })  
            }
}

2、在项目index页面测试

import service from '../../common/my_serve.js'
//在onLoad(){}钩子中调用预登录函数
async onLoad() {   
            const can_login = await service.pre_login()    
            if(can_login){        
                this.fast_login()    
             }
        },
methods: {    
            async fast_login() {       
                try{            
                    const { access_token, openid } = await service.fast_login()            
                    console.log("uniapp一键登录", access_token, openid,29)            // 登录操作,获取token和用户信息等操作        
                }catch(e){            
                    console.log('一键登录失败', e)        
                    }    
                },
            },

代码生成效果如下:


一键登录全屏页面.jpg

坑三:
真机调试报错 -20202是非流量的问题,需要开启手机流量

坑四:
预登录失败 perLogin: fail
-当前客户端和HBuilderX不在同一局域网下(或其他网络原因无法连接HBuilderX),uniCloud本地调试服务不对当前客户端生效。
-如果不使用uniCloud本地调试服务,请直接忽略此信息。
-如需使用uniCloud本地调试服务,请将客户端与主机连接到同一局域网下并重新运行到客户端。
-如果在HBuilderX开启的状态下切换过网络环境,请重启HBuilderX后再试
-检查系统防火墙是否拦截了HBuilderX自带的nodejs
早上调试还是正常的,晚上后就报这个错,目前基本还没找到切实可行的解决方案,官方有声明说在3.6.4中修复了这个bug,但我3.6.4还是出现这个问题,更换版本,重新安装手机调试基座都试过,无用,第二天早上换了几次HBuilderX版本后莫名奇妙的好了,无语。。。

坑五:
报错云函数调用失败:access_token undefined, 要在https://dev.dcloud.net.cn/uniLogin 的一键登录中充一点钱, 就成功了

预登录以及一键登录获取手机号成功.png

其他补充

通过传统服务器连接uniCloud云函数

开发者也可以在客户端获取到access_token等信息后,传给自己的传统服务器。然后由自己的传统服务器,访问uniCloud的云函数(需将云函数URL化)。
参考官方文档https://uniapp.dcloud.net.cn/univerify.html#%E7%94%A8access-token%E6%8D%A2%E6%89%8B%E6%9C%BA%E5%8F%B7 说的挺详细的;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容