微信小程序授权流程详解

2,402 阅读4分钟

让你明明白白学知识,有代码,有讲解,抄的走,学的会!

微信授权,需要经过用户主动触发,不能使用静默授权,直接调即可取获取用户数据,是不符合微信规范,在发布的时候,会被打回

外观样式

视图层


<view class="login-wrapper">
    <button 
        class='login-btn' 
        type='primary' 
        open-type="getUserInfo" 
        lang="zh_CN" 
        bindgetuserinfo="bindGetUserInfo"
    >
	授权登录
    </button>
    <button class='cancel-btn'  bindtap="cancelLogin">取消</button>
</view>

逻辑层

const {getWxCodeAPI} = require("../../apis/index")

Page({
    // 取消按钮
    cancelLogin() {
        // getCurrentPages()获取页面栈个数
        if(getCurrentPages().length === 1) {
          wx.navigateTo({
            url: '/pages/order/index',
          })
        } else {
          wx.navigateBack()
        }
    },
    // 获取头像
  async bindGetUserInfo() {
    let self = this;
    
    wx.getSetting({
      success: res => {
        console.log("res", res)
        // 用户同意了
        if (res.authSetting['scope.userInfo']) {
          console.log("已授权=====")
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称
          wx.getUserInfo({
            success(res) {
              console.log("获取用户信息成功", res)
                
            // 将头像信息存储起来
              wx.setStorageSync('userInfo', res.rawData)

              // 直接调用登录接口--自己后台的登录系统接口
              self.login()
            },
            fail(res) {
              console.log("获取用户信息失败", res)
            }
          })
        } else {
          console.log("未授权=====")
          wx.showModal({
            title: '提示',
            content: '授权失败,请授权后继续操作',
            success(res) {
              // 不需要做什么事情
            }
          })
        }
      }
    })
  },
  login() {
    // 在这个地方,就调用自己后台的登陆接口
    getWxCodeAPI(() => {
        // 登录以后的回调方法
        wx.switchTab({
          url: '/pages/form/form',
        })
    })
  }
})

当用户点击授权,就会弹出授权窗口,点击允许,即可

  1. 上面其实我是在拿到用户头像以后,就直接去调用 wx.login 拿到用户的appid的code,这个code是微信生成的,获取code是没有和我们自己的服务端有任何交互请求的;

  2. 拿到code以后,我们才去调自己后台的登录接口,将code传过去,后台通过code能够获取到用户的信息,并存储,完成【注册/登录】

现在看一下 getWxCodeAPI这个api中做了什么事情

/apis/index.js

const {getUserAppidAPI} = require("../../utils/index")

// 自己后台的登录接口,这里比较简洁,可以自己封装 request
const loginAPI = (code)=> {
    wx.request({
        .....
    })
}

/**
 * 获取微信的code
 * @param {*} callback 登录自己系统以后的回调
 */
const getWxCodeAPI = async (callback)=> {
  // 将用户的appid 拿到,这个不需要授权
  let code = await getUserAppidAPI()
  console.log(code)
  if (!code || typeof code !== 'string') {
    toast('微信登录失败')
    wx.removeStorageSync('code')
    wx.removeStorageSync('token')
    return
  }

  // 调用自己后台登录接口
  let res = await loginAPI({
    code
  })
  let data = res.data

  if (data.code !== 0) {
    wx.showModal({
      title: "登录失败",
      content: res.data.data.msg || ""
    })
    wx.removeStorageSync('code')
    wx.removeStorageSync('token')
  } else {
    // 存储用户token
    wx.setStorageSync('token', res.data.data.token)

    callback && callback()
  }
}

module.exports = {
    getWxCodeAPI
}

/utils/index.js

/**
 * 获取微信生成的code
 */
const getUserAppidAPI = ()=> {
  return new Promise((resolve, reject)=> {
    wx.login({
      success (res) {
        if (res.code) {
          //发起网络请求
          // 直接存起来-- 这个code 5分钟就过期了
          wx.setStorageSync('code', res.code)
          resolve(res.code)
        } else {
          wx.removeStorageSync('code')
          console.log('登录失败!' + res.errMsg)
        }
      }
    })
  })
}

module.exports = {
    getUserAppidAPI
}

代码分析

getWxCodeAPI中:

  1. 调用已经封装好的 获取wx.login中的code的接口, 使用Promise包了一层,不想使用Promise,就用回调函数
  2. 拿到code以后,去调自己后台的登录接口,并将后台登录的token存储到 本地,以方便其他界面读取
  3. getWxCodeAPI 预留了一个callback,可能我们在登录以后,需要做跳转,但是具体跳转到哪里,应用场景不同,就没做具体的控制,让回调函数去执行,当然,这里也可以使用Promise包装一层

取消按钮逻辑

  1. 假设用户,进入登录界面以后,并不想登录,想继续在小程序中浏览看看,此时,你不能指定跳转到哪一个界面,因为你需要跳转到用户访问过的那个界面

  2. 假设,用户一进入小程序,就是这个登录界面,你可能知道你需要跳转到某个具体界面A

针对上面2中情况,我们这里的取消逻辑就是

先获取页面栈 getCurrentPages() 个数,length = 1,那么就跳转到具体界面,表示是第二种情况

length > 1 则表示有后退操作,就调用 wx.navigateBack() 方法

有时候,这个登录界面只是一个中间的过渡页面,登录完成以后,还需要返回上一个界面,此时, getCurrentPages() (微信提供的全局方法) 就可以知道,当前页面栈有多少个

如果,页面栈的长度为1,也就是说,最新的页面就是当前页面,再去调用 wx.navigateBack() 将报错

重点

  • 微信为了规范使用用户信息,一些敏感信息都是要用户主动同意,才能获取,不能静默获取数据
  • wx.login获取的code 是不是敏感数据,可以直接静默获取,且这个code 5分钟就过期了, 所以,我们调后台接口,形成自己的登录,就是为了在code没过期之内,将用户数据存储起来
  • 一定要使用button按钮,来调起授权弹窗,否则微信发布的时候,或者控制台将给你报错
<button open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授权登录</button>
  • 这里只是获取用户的头像权限,还有 其他的权限,思路是一样的,先用户授权,再调微信API获取

微信官方文档

番外篇

简单封装wx.request

/apis/request.js

const baseURL = 'http://www.test.cn'

module.exports.request = function (url, method = 'post', data = {}) {
  return new Promise((resolve, reject) => {
    wx.request({
      url: baseURL + url,
      data,
      header: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      method,
      success: res => {
        resolve(res.data)
      },
      fail: err => {
        // toast('网络故障,请稍后重试')
        reject(err)
      }
    })
  })
}

这个是最简单的,根据自己的场景,去封装工具,仅供参考