使用dcloud全家桶开发公众号H5系统

从微信中获取用户昵称头像

小韦云科技-区块链+小程序+公众号+商城+分销+直播+企业官网+外贸电商-为您提供优质的开发服务-电话/微信联系:18123611282

上一节我们使用openid完成了注册和登录,但uni-id里的用户信息都是空的,这一节我们将实现在微信中获取用户昵称头像。

类似获取openid流程,获取用户信息也是需要跳转页面的,并且还需要用户确认授权才能获取到信息

完整的代码请在官方插件市场下载:https://ext.dcloud.net.cn/plugin?id=4829

代码已加详细说明

async getWeixinUserInfo() {
                //如果缓存存在,则直接返回
                let user = uni.getStorageSync('wx-user')
                if (user) return user

                //本地无法跳转,不能获取user
                if (window.location.href.indexOf('localhost') != -1) return false;

                //先取uid,保存获取用户信息之前已经通过openid完成注册登录
                let uid = await this.getUid()
                if (!uid) return false;

                //先读取公众号配置
                let config = await this.bctosCommon('config')
                let appid = config.result.appId
                let secret = config.result.appSecret

                //获取微信跳转带回来的参数
                let option = this.getGetParam()
                if (typeof(option.state) == "undefined" || option.state != 'bctos') { //第一步:用户同意授权,获取code
                    let redirect_uri = encodeURIComponent(location.href.split('#')[0])
                    window.location.href = 'https://open.weixin.qq.com/connect/oauth2/' +
                        `authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=bctos#wechat_redirect`
                } else if (typeof(option.state) != "undefined" && option.state == 'bctos') {
                    //第二步:通过code换取网页授权access_token
                    if (!typeof(option.code) || option.code == '') {
                        this.error('获取code失败')
                    } else {
                        //前端不能跨域请求微信服务器,只能通过云函数代请求, 获取openid和access_token
                        let res = await this.bctosCommon('jsonp', {
                            url: 'https://api.weixin.qq.com/sns/oauth2/access_token?grant_type=authorization_code' +
                                `&appid=${appid}&secret=${secret}&code=${option.code}`
                        })
                        let data = res.result.data
                        if (typeof(data) != "object" || typeof(data.openid) == "undefined") {
                            this.error(JSON.stringify(data))
                        } else {
                            uni.setStorageSync('openid', data.openid)

                            //获取用户信息
                            res = await this.bctosCommon('jsonp', {
                                url: `https://api.weixin.qq.com/sns/userinfo?access_token=${data.access_token}&openid=${data.openid}&lang=zh_CN`
                            })
                            if (typeof(res.result.data) != "object" || typeof(res.result.data.openid) == "undefined") {
                                this.error(JSON.stringify(res.result.data))
                            } else {
                                //获取的结果缓存在前端
                                uni.setStorageSync('wx-user', res.result.data)
                                //获取的结果保存到uni-id的用户表中
                                this.bctosCommon('saveUserInfo', {
                                    uid,
                                    ...res.result.data
                                })
                                return res.result.data
                            }
                        }
                    }
                }
                return false
            }

虽然它调用它后端云函数jsonp,但它只是一个代获取远程信息的作用,代码如下

            if (!event.method) {
                event.method = 'GET'
            }
            if (!event.data) {
                event.data = {}
            }
            if (!event.dataType) {
                event.dataType = 'json'
            }
            res = await uniCloud.httpclient.request(event.url, {
                method: event.method,
                data: event.data,
                dataType: event.dataType
            })

因为如果直接在前端使用uni.request请求的话,会报跨域错误,只能使用后端uniCloud.httpclient.request方法来请求。

得到结果后保存到uni-id的代码如下

            let save = {
                uid: event.uid,
                wx_openid: event.openid,
                nickname: event.nickname,
                gender: event.sex,
                province: event.province,
                city: event.city,
                country: event.country,
                avatar: event.headimgurl
            }
            if (typeof(event.unionid) != "undefined") save.wx_unionid = event.unionid

            res = await uniID.updateUser(save)

其中国家(country),省(province),市(city)这三个字段有uni-id的用户表结构中是没有定义的,但不影响数据的保存

本文由小韦云原创,转载请注明出处:https://bctos.cn/doc/18/1962,否则追究其法律责任

关键词:昵称 头像

广告位招商