• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

uni-app云开发--微信登录

武飞扬头像
Biao
帮助1

前言

我们主要使用uniapp uniCloud 实现小程序登录,并将用户数据存入云数据库。

小程序 wx.getUserProfile 调整,接口将被收回 详情,所以需要用户自己填写资料。

注:填写个人资料是一个组件,覆盖在登录之上而已,还是在同一个页面

学新通学新通

uniCloud

创建 uniapp uniCloud 项目,创建云数据库 数据表 uniCloud传送门

开始

创建项目

学新通

关联云服务空间

学新通 学新通

创建云数据库 数据表

不使用模版,输入名称直接创建即可。

学新通

编辑表结构,想了解更多可以去看云数据库 DB Schema 数据结构文档 传送门

{
  "bsonType": "object",
  "required": [],
  "permission": {
    "read": true,
    "create": true,
    "update": true,
    "delete": false
  },
  "properties": {
    "_id": {
      "description": "ID,系统自动生成"
    },
    "nickName": {
      "bsonType": "string",
      "label": "昵称",
      "description": "用户昵称,登录获取的"
    },
    "avatarUrl": {
      "bsonType": "string",
      "label": "头像",
      "description": "用户头像图片的 URL,登录获取的"
    },
    "gender": {
      "bsonType": "number",
      "label": "性别",
      "description": "用户性别,1: 男;2: 女"
    },
	"personalize": {
	  "bsonType": "string",
	  "label": "个性签名",
	  "description": "个性签名,编辑资料获取"
	},
	"background": {
	  "bsonType": "object",
	  "label": "个人中心背景图",
	  "description": "个人中心背景图,编辑资料获取"
	},
    "mp_wx_openid": {
      "bsonType": "string",
      "description": "微信小程序平台openid"
    },
    "register_date": {
      "bsonType": "timestamp",
      "description": "注册时间",
      "forceDefaultValue": {
        "$env": "now"
      }
    }
  }
}

创建云函数

学新通 学新通

云函数代码

云函数 将 uni.login 取得的 code 获取到用户 session, 并对 数据库进行 增加、修改、查询 操作,第一次注册必须用户主动填写用户资料。

对云数据库的相关操作 传送门

'use strict';

//小程序的AppID 和 AppSecret
const mp_wx_data = {AppID: '************', AppSecret: '***********************'}

//event为客户端上传的参数
exports.main = async (event, context) => {    

    //使用云数据库
    const db = uniCloud.database();    
    // 获取 `users` 集合的引用
    const pro_user = db.collection('users');
    // 通过 action 判断请求对象

    let result = {};
    switch (event.action) {        
        // 通过 code 获取用户 session
        case 'code2Session':
            const res_session = await uniCloud.httpclient.request('https://api.weixin.qq.com/sns/jscode2session', {
                    method: 'GET', data: {
                        appid: mp_wx_data.AppID,
                        secret: mp_wx_data.AppSecret,
                        js_code: event.js_code,
                        grant_type: 'authorization_code'
                    }, dataType: 'json'
                }
            )
            const success = res_session.status === 200 && res_session.data && res_session.data.openid
            if (!success) {
                return {
                    status: -2, msg: '从微信获取登录信息失败'
                }
            }
            
            //从数据库查找是否已注册过
            const res_user = await pro_user.where({
                mp_wx_openid: res_session.data.openid
            }).get()
            // 没有用户信息,进入注册
            if (res_user.data && res_user.data.length === 0) {
                //event.user_info 用户信息
                if (event.user_info) {
                    //有信息则进入注册,向数据库写入数据
                    const register = await uniCloud.callFunction({
                        name: 'user',
                        data: {
                            action: 'register',
                            open_id: res_session.data.openid,
                            user_info: event.user_info
                        }
                    }).then(res => {
                        result = res
                    })
                } else {
                    //没有信息返回{register: true}
                    result = {
                        result: {
                            result: {register: true}
                        }
                    }
                }
            } else {
                result = {
                    result: {
                        result:  res_user.data[0]
                    }
                }
            }
            break;
        //注册 向数据库写入数据
        case 'register':
            const res_reg = await pro_user.add({
                nickName: event.user_info.nickName,
                avatarUrl: event.user_info.avatarUrl,
                gender: event.user_info.gender,
                mp_wx_openid: event.open_id,
                register_date: new Date().getTime()
            })
            if (res_reg.id) {
                const res_reg_val = await uniCloud.callFunction({
                    name: 'user', data: {
                        action: 'getUser', open_id: event.open_id
                    }
                }).then(res => {
                    result = res
                })
            } else {
                result = {
                    status: -1, msg: '微信登录'
                }
            }
            break;
        case 'update':
            if (event._id && event.info) {
                const res_update = await pro_user.doc(event._id).update(event.info)
                if (res_update.updated >= 0) {
                    result = {status: 200, msg: '修改成功'}
                } else {
                    result = {status: -1, msg: '修改失败'}
                }
            } else {
                result = {status: -1, msg: '修改失败'}
            }
            break;
        case 'getUser':
            const res_val = await pro_user.where({
                mp_wx_openid: event.open_id
            }).get()
            return res_val.data[0]
            break;
    }
    return result;
};

微信登录操作

如上面所说,用户需手动上传资料,对于用户头像我们需要上传至云储存。

上传用户头像

上传图片函数参数为微信本地图片路径,我们对路径用/进行分割,取最后的图片名称进行上传

/**
 * 上传图片至云存储
 */
export async function uploadImage(url) {
    const fileName = url.split('/')
    return new Promise(resolve => {
        uniCloud.uploadFile({
            filePath: url,
            cloudPath: fileName[fileName.length - 1],
            success(res) {
                resolve(res)
            },
            fail() {
                uni.showToast({
                    title: '图片上传失败!',
                    icon: 'none'
                })
                resolve(false)
            }
        })
    })
}

登录函数

如果用户第一次上传资料,我们需要先上传头像并取得图片链接,再将用户资料写入数据库。

async wxLogin() {
      if (this.userInfo && this.userInfo.avatarUrl) {
        uni.showLoading({
          title: '正在上传图片...',
          mask: true
        });
        //上传头像至云储存并返回图片链接
        const imageUrl = await uploadImage(this.userInfo.avatarUrl)
        if (!imageUrl) {
          return
        }
        this.userInfo = {...this.userInfo, avatarUrl: imageUrl.fileID}
      }
      uni.showLoading({
        title: '登陆中...',
        mask: true
      });
      const _this = this
      uni.login({
        provider: 'weixin',
        success: (res) => {
          if (res.code) {
            //取得code并调用云函数
            uniCloud.callFunction({
              name: 'user',
              data: {
                action: 'code2Session',
                js_code: res.code,
                user_info: _this.userInfo
              },
              success: (res) => {
                 //如register为true,用户未填写资料
                if (res.result.result.result.register) {
                   //_this.showUserInfo 显示填写资料组件
                  _this.showUserInfo = true
                  uni.hideLoading();
                  return
                }
                if (res.result.result.result._id) {
                  const data = {
                    _id: res.result.result.result._id,
                    mp_wx_openid: res.result.result.result.mp_wx_openid,
                    register_date: res.result.result.result.register_date
                  }
                  this.loginSuccess(data)
                }
              },
              fail: () => {
                this.loginFail()
              }
            })
          }
        }
      })
    },

登录成功与失败

在用户登录成功后将数据存入 Storage 中,添加登录过期时间,我这里设置的是七天的登录有效期。

loginSuccess(data) {
      updateTokenStorage(data)
      updateIsLoginStorage(true)
      uni.showToast({
        title: '登陆成功!',
        icon: 'none'
      });
      uni.navigateBack()
    },

将用户数据存入 Storage,并设置过期时间 expiresTime

export function updateTokenStorage(data = null) {
    if (data) {
        const expiresTime = new Date().getTime()   7 * 24 * 60 * 60 * 1000
        data = {...data, expiresTime: expiresTime}
    }
    uni.setStorageSync('user', data)
}

isLogin 用于判断是否是否登录

export function updateIsLoginStorage(data = null) {
    uni.setStorageSync('isLogin', data)
}

登录失败

loginFail() {
      updateTokenStorage()
      updateIsLoginStorage()
      uni.showToast({
        title: '登陆失败!',
        icon: 'none'
      });
    }

判断是否登录

除了判断 isLogin 还要判断 expiresTime 是否登录过期

//判断是否登陆
export function isLogin() {
    try {
        const user = uni.getStorageSync('user')
        const isLogin = uni.getStorageSync('isLogin')
        const nowTime = new Date().getTime()
        return !!(isLogin && user && user._id && user.expiresTime > nowTime);
    } catch (error) {

    }
}

最后

至此就实现了微信登录并将用户信息存入数据库中,我们也可以通过云函数获取用户数据,做出用户个人主页。

学新通

以上是我做个人小程序时用的登录流程,整个小程序项目已上传至 GitHub。

GitHub地址

小程序码

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgajgbi
系列文章
更多 icon
同类精品
更多 icon
继续加载