mpVue 微信小程序用户授权及wx.getUserProfile代替wx.getUserInfo获取用户信息及判断用户是否已经授权;不弹出微信授权窗口;只能使用头像、昵称填写能力

2023-11-14

一、前言

2021年4月15日整改:为优化用户的使用体验,平台将进行以下调整
1,2021年2月23日起,若小程序已在微信开放平台进行绑定,则通过wx.login接口获取的登录凭证可直接换取unionID
2,2021年4月13日后发布的小程序新版本,无法通过wx.getUserInfo与获取用户个人信息(头像、昵称、性别与地区),将直接获取匿名数据(包括userInfoencryptedData中的用户个人信息),获取加密后的openIDunionID数据的能力不做调整。此前发布的小程序版本不受影响,但如果要进行版本更新则需要进行适配。
3,新增getUserProfile接口(基础库2.10.4版本开始支持),可获取用户头像、昵称、性别及地区信息,开发者每次通过该接口获取用户个人信息均需用户确认。具体接口文档:《getUserProfile接口文档》

自 2022 年 10 月 25 日 24 时后(以下统称 “生效期” ),用户头像昵称获取规则将进行如下调整
1、自生效期起,小程序 wx.getUserProfile 接口将被收回:生效期后发布的小程序新版本,通过 wx.getUserProfile 接口获取用户头像将统一返回默认灰色头像,昵称将统一返回 “微信用户”。生效期前发布的小程序版本不受影响,但如果要进行版本更新则需要进行适配。
2、自生效期起,插件通过 wx.getUserInfo 接口获取用户昵称头像将被收回:生效期后发布的插件新版本,通过 wx.getUserInfo 接口获取用户头像将统一返回默认灰色头像,昵称将统一返回 “微信用户”。生效期前发布的插件版本不受影响,但如果要进行版本更新则需要进行适配。通过 wx.loginwx.getUserInfo 接口获取 openIdunionId 能力不受影响。
3、「头像昵称填写能力」支持获取用户头像昵称:如业务需获取用户头像昵称,可以使用「头像昵称填写能力」(基础库 2.21.2 版本开始支持)。
4、小程序 wx.getUserProfile插件 wx.getUserInfo 接口兼容基础库 2.21.2 以下版本的头像昵称获取需求:上述「头像昵称填写能力」从基础库 2.21.2 版本开始支持(覆盖微信 8.0.16 以上版本)。对于来自更低版本的基础库与微信客户端的访问,小程序通过wx.getUserProfile接口将正常返回用户头像昵称,插件通过 wx.getUserInfo 接口将返回用户头像昵称,开发者可继续使用以上能力做向下兼容。

二、微信小程序授权及登录流程

1、调起 wx.getUserProfile 获取用户微信的基本资料
2、通过 wx.login 获取唯一 code,将 code 调用后台接口获取 openid/unionid
3、根据openid/unionid调用后台接口,获取微信登录的token

三、关键步骤(wx.getUserProfile代替wx.getUserInfo使用)

1、template改变对比

<!-- 旧版本 -->
<button open-type="getUserInfo" @getuserinfo="bindGetUserInfo">微信授权</button>
<!-- 新版本 -->
<button @click="bindGetUserInfo">微信授权</button>

2、bindGetUserInfo方法对比

// 旧版
    // 用户按了允许授权按钮
    bindGetUserInfo(e) {
      if (e.mp.detail.userInfo) {
        // 用户按了允许授权按钮
        // console.log('用户的信息:', e.mp.detail.userInfo)
        this.canGetInfo = true
        // 存储微信用户信息
        this.setWxUserInfo(e.mp.detail.userInfo)
        // 存储头像
        this.setAvatarUrl(e.mp.detail.userInfo.avatarUrl)
        wx.hideLoading()
        this.logining()
      } else {
        // 用户按了拒绝按钮
        wx.hideLoading()
        wx.showModal({
          title: '提示',
          content: '拒绝授权将无法注册登陆小程序!',
          showCancel: false,
          success: (res) => {
            if (res.confirm) {
              this.canGetInfo = true
            }
          }
        })
      }
    },
    // 查看是否授权
    getWxInfo() {
      wx.showLoading({
        title: '检查授权情况',
        mask: true
      })
      wx.getSetting({
        success: (res) => {
          if (res.authSetting['scope.userInfo']) {
            wx.getUserInfo({
              success: (data) => {
                // 用户已经授权过,不需要显示授权页面
                this.canGetInfo = true
                // console.log('获取微信用户信息', data, this.openId)
                this.setWxUserInfo(data.userInfo)
                this.setAvatarUrl(data.userInfo.avatarUrl)
                // 调用微信登录wx.login
                this.logining()
              }
            })
          } else {
            // 用户没有授权,显示授权页面
            this.canGetInfo = false
            console.log('用户还未授权', res)
          }
        }
      })
    },
    
//新版
 // 查看是否授权
    bindGetUserInfo() {
      wx.showLoading({
        title: '请求授权中...',
        mask: true
      })
      if (this.wxUserInfo.avatarUrl) {
        console.log('获取微信用户信息--', this.wxUserInfo)
        // 用户已经授权过,不需要显示授权页面
        this.canGetInfo = true
        console.log('用户已经授权过22222---')
        // 调用微信登录wx.login
        this.logining()
      } else {
        wx.getUserProfile({
          desc: '必须授权才能继续使用',
          success: (data) => {
            this.canGetInfo = true
            console.log('获取微信用户信息', data)
            wx.hideLoading()
            this.setWxUserInfo(data.userInfo)
            this.setAvatarUrl(data.userInfo.avatarUrl)
            // 调用微信登录wx.login
            this.logining()
          },
          fail: (error) => {
            this.canGetInfo = false
            wx.hideLoading()
            console.log('用户还未授权', error)
          }
        })
      }
    },

3、判断用户是否已经授权

授权弹窗:是自己css布局的界面弹窗(因为自 2022 年 10 月 25 日 24 时后,是否显示微信授权弹窗都需要用户手动点击触发);因为wx.getUserProfilewx.getUserInfo都已经被收回所有都不弹出授权窗口,只能使用头像昵称填写能力

1、旧版根据wx.getSetting['scope.userInfo']来判断是否已经授权过

2、新版是判断 是否存储过微信的用户信息,有则已经授权过,没有则弹出授权弹窗(自己css布局弹窗)

四、具体授权完整步骤

1、旧版授权方法( wx.getUserInfo使用),如下:

<template>
  <div class="auth flex-box flex-ver">
    <!-- 获取权限 -->
    <section v-if="!canGetInfo" class="sec-mask">
      <div class="wrapper flex-box flex-ver flex-col">
        <img class="wechat-auth-img" src="../../static/images/logo.png" />
        <p class="hint">小程序希望获取您的微信授权</p>
        <button
          class="btn flex-box flex-ver"
          type="primary"
          open-type="getUserInfo"
          @getuserinfo="bindGetUserInfo"
        >微信授权</button>
      </div>
    </section>
  </div>
</template>
<script>
export default {
  name: 'Auth',
  data() {
    return {
      code: '', // wx.login拿回来的code
      canGetInfo: true // 授权状态,能否获取用户信息
    }
  },
  computed: {
    ...mapGetters([
      'userType', // 当前登录用户 EXTERNAL_DRIVER-司机 EXTERNAL_SUP-供应商
      'openId',
      'userInfo',
      'unionId',
      'mpBinding'
    ])
  },
  onShow() {
    this.getWxInfo()
  },
  methods: {
    ...mapMutations({
      setAvatarUrl: 'user/SET_AVATAR_URL',
      setToken: 'user/SET_TOKEN',
      setOpenId: 'user/SET_OPEN_ID',
      setUnionId: 'user/SET_UNION_ID',
      setWxUserInfo: 'user/SET_WX_USER_INFO'
    }),
    // 用户按了允许授权按钮
    bindGetUserInfo(e) {
      if (e.mp.detail.userInfo) {
        // 用户按了允许授权按钮
        // console.log('用户的信息:', e.mp.detail.userInfo)
        this.canGetInfo = true
        // 存储微信用户信息
        this.setWxUserInfo(e.mp.detail.userInfo)
        // 存储头像
        this.setAvatarUrl(e.mp.detail.userInfo.avatarUrl)
        wx.hideLoading()
        // 调用微信登录wx.login
        this.logining()
      } else {
        // 用户按了拒绝按钮
        wx.hideLoading()
        wx.showModal({
          title: '提示',
          content: '拒绝授权将无法注册登陆小程序!',
          showCancel:false,
          success: (res) => {
            if (res.confirm) {
              this.canGetInfo = false
            }
          }
        })
      }
    },
    // 查看是否授权
    getWxInfo() {
      wx.showLoading({
        title: '检查授权情况',
        mask: true
      })
      wx.getSetting({
        success: (res) => {
          if (res.authSetting['scope.userInfo']) {
            wx.getUserInfo({
              success: (data) => {
                // 用户已经授权过,不需要显示授权页面
                this.canGetInfo = true
                // console.log('获取微信用户信息', data, this.openId)
                this.setWxUserInfo(data.userInfo)
                this.setAvatarUrl(data.userInfo.avatarUrl)
                // 调用微信登录wx.login
                this.logining()
              }
            })
          } else {
            // 用户没有授权,显示授权页面
            this.canGetInfo = false
            console.log('用户还未授权', res)
          }
        }
      })
    },
    // 调用微信登录wx.login获取code
    logining() {
      wx.showLoading({
        title: '登录微信用户',
        mask: true
      })
      wx.login({
        success: (res) => {
          if (res.code) {
            wx.hideLoading()
            // 通过code获取openid和session_key
            this.code = res.code
            // console.log('wx.login获得code成功', res)
            // 调用获取用户信息接口
            if (this.openId) {
              // vuex中的openId/unionId
              this.getAccessToken(this.openId)
            } else {
              this.getAsyncOpenId({ code: this.code })
            }
          } else {
            console.log('获取用户登录态失败!' + res.errMsg)
          }
        },
        fail(err) {
          wx.hideLoading()
          wx.showToast({
            title: 'wx.login失败' + err,
            icon: 'none',
            duration: 1000
          })
        }
      })
    },
    // 获取openid
    async getAsyncOpenId(parameter) {
      wx.showLoading({
        title: '获取openId',
        mask: true
      })
      const res = await this.$http('getOpenId', parameter)
      // console.log('获取openId', res)
      wx.hideLoading()
      if (res.success) {
        // 生成唯一值
        this.setOpenId(res.data.openid)
        // console.log('获取openId---值', res.data.openid)
        this.getAccessToken(res.data.openid)
      }
    },
    // 获取token
    async getAccessToken(openId) {
      const res = await this.$http('getAccessToken', { openId })
      if (res.data.success) {
        this.setToken(res.data.data)
        wx.showLoading({
          title: '获取用户信息',
          mask: true
        })
        // 获取登录用户的user信息
        const userRole = await this.$store.dispatch('user/getUserInfo')
        // console.log('userRole---', userRole)
        if (userRole.success) {
          wx.hideLoading()
          const findRole = userRole.data.post
          //进入首页
          if (findRole) {
            this.$reLaunch('/pages/tabbarPage/main')
          } else {
            wx.showToast({
              title: '当前用户未绑定合法角色',
              icon: 'none',
              duration: 3000
            })
          }
        }
      } else {
        switch (res.data.code) {
          case 10000:
            this.$reLaunch('/pages/register/main')
            break
          case 10009:
            // console.log('直接进入首页')
            this.$reLaunch('/pages/tabbarPage/main')
            break
          case 11002:
          case 11003:
            this.loginErr(`获取token失败,${res.msg}`)
            break
        }
      }
    },
    // 当前用户未绑定、登录失败、异常等
    loginErr(msg = '') {
      const query = this.$mp.query
      // console.log('query--', query)
      wx.showModal({
        title: '登录失败',
        content: msg,
        confirmText: '刷新',
        showCancel: false,
        success: () => {
          this.$reLaunch(`/pages/auth/main`)
        }
      })
    }
  }
}
</script>

2、新版授权方法(wx.getUserProfile),如下:

<template>
  <div class="auth flex-box flex-ver">
    <!-- 获取权限 -->
    <section v-if="!canGetInfo" class="sec-mask">
      <div class="wrapper flex-box flex-ver flex-col">
        <img class="wechat-auth-img" src="../../static/images/logo.png" />
        <div class="flex-box flex-col">
          <p class="hint t-font-size-16">申请获取以下权限</p>
          <div class="t-margin-top-5" style="color: #9d9d9d;">获得你的公开信息(昵称,头像等)</div>
        </div>
        <button class="btn flex-box flex-ver" type="primary" @tap="getWxInfo">微信授权</button>
      </div>
    </section>
  </div>
</template>
<script>
import { mapMutations, mapGetters } from 'vuex'
export default {
  name: 'Auth',
  data() {
    return {
      code: '', // wx.login拿回来的code
      canGetInfo: false // 授权状态,能否获取用户信息
    }
  },
  computed: {
    ...mapGetters([
      'userType', // 当前登录用户 EXTERNAL_DRIVER-司机 EXTERNAL_SUP-供应商
      'openId',
      'userInfo',
      'unionId',
      'mpBinding',
      'wxUserInfo'
    ])
  },
  onShow() {
    this.getWxInfo()
  },
  methods: {
    ...mapMutations({
      setAvatarUrl: 'user/SET_AVATAR_URL',
      setToken: 'user/SET_TOKEN',
      setOpenId: 'user/SET_OPEN_ID',
      setWxUserInfo: 'user/SET_WX_USER_INFO'
    }),
    // 查看是否授权
    getWxInfo() {
      wx.showLoading({
        title: '请求授权中...',
        mask: true
      })
      // 判断用户是否已经授权,若已经授权直接调用wx.login,不然则先调用wx.getUserProfile
      if (this.wxUserInfo.avatarUrl) {
        console.log('1111', this.wxUserInfo)
        this.canGetInfo = true
        console.log('用户已经授权过')
        // 调用微信登录wx.login获取code
        this.logining()
      } else {
        wx.getUserProfile({
      	  desc: '获取用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中(必填项)
          success: (data) => {
            this.canGetInfo = true
            wx.hideLoading()
            // 存储微信userInfo
            this.setWxUserInfo(data.userInfo)
            // 存储微信头像
            this.setAvatarUrl(data.userInfo.avatarUrl)
            // 调用微信登录wx.login获取code
            this.logining()
          },
          fail: (error) => {
            this.canGetInfo = false
            wx.hideLoading()
            console.log('用户还未授权', error)
          }
        })
      }
    },
    // 调用微信登录wx.login获取code
    logining() {
      wx.showLoading({
        title: '登录微信用户',
        mask: true
      })
      wx.login({
        success: (res) => {
          if (res.code) {
            wx.hideLoading()
            // 通过code获取openid和session_key
            this.code = res.code
            // console.log('wx.login获得code成功', res)
            // 判断若存在openId/unionId,则直接去获取token,不然则先获取openId,在去获取token
            if (this.openId) {
              this.getAccessToken(this.openId)
            } else {
              this.getAsyncOpenId({ code: this.code })
            }
          } else {
            console.log('获取用户登录态失败!' + res.errMsg)
          }
        },
        fail(err) {
          wx.hideLoading()
          wx.showToast({
            title: 'wx.login失败' + err,
            icon: 'none',
            duration: 1000
          })
        }
      })
    },
    // 获取openid
    async getAsyncOpenId(parameter) {
      wx.showLoading({
        title: '获取openId',
        mask: true
      })
      const res = await this.$http('getOpenId', parameter)
      // console.log('获取openId', res)
      wx.hideLoading()
      if (res.success) {
        // 生成唯一值
        this.setOpenId(res.data.openid)
        // console.log('获取openId---值', res.data.openid)
        this.getAccessToken(res.data.openid)
      }
    },
    // 获取token
    async getAccessToken(openId) {
      const res = await this.$http('getAccessToken', { openId })
      if (res.data.success) {
        this.setToken(res.data.data)
        wx.showLoading({
          title: '获取用户信息',
          mask: true
        })
        // 获取用户user信息
        const userRole = await this.$store.dispatch('user/getUserInfo')
        // console.log('userRole---', userRole)
        if (userRole.success) {
          wx.hideLoading()
          // 获取角色
          const findRole = userRole.data.post
          // 进入首页
          if (findRole) {
            this.$reLaunch('/pages/tabbarPage/main')
          } else {
            wx.showToast({
              title: '当前用户未绑定合法角色',
              icon: 'none',
              duration: 3000
            })
          }
        }
      } else {
        switch (res.data.code) {
          case 10000:
            // console.log('进入注册页面')
            this.$reLaunch('/pages/register/main')
            break
          case 10009:
            // console.log('直接进入首页')
            this.$reLaunch('/pages/tabbarPage/main')
            break
          case 11002:
          case 11003:
            this.loginErr(`获取token失败,${res.msg}`)
            break
        }
      }
    },
    // 当前用户未绑定、登录失败、异常等
    loginErr(msg = '') {
      const query = this.$mp.query
      wx.showModal({
        title: '登录失败',
        content: msg,
        confirmText: '刷新',
        showCancel: false,
        success: () => {
          this.$reLaunch(`/pages/auth/main`)
        }
      })
    }
  }
}
</script>
<style lang="scss">
.auth {
  height: 100%;
  .loading-wrap {
    padding-bottom: 160px;
    .launch_loading_logo {
      width: 50px;
      height: 50px;
      border-radius: 50px;
    }
    .app-name {
      margin-top: 20px;
    }
  }
  /* 授权页样式 */
  .sec-mask {
    background: rgba(0, 0, 0, 0.4);
    position: fixed;
    display: flex;
    justify-content: center;
    align-items: center;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 99;
    .wrapper {
      width: 90%;
      height: 40%;
      background-color: #fff;
      border-radius: 8rpx;
      .wechat-auth-img {
        display: block;
        width: 162px;
        height: 143px;
      }
      .hint {
        margin-top: 30rpx;
      }
      button {
        width: 80%;
        height: 100rpx;
        background-color: #259b24;
        border-radius: 70rpx;
        margin-top: 60rpx;
      }
    }
  }
}
</style>

3、效果,如下:

在这里插入图片描述

源码地址

gitHub地址

码云地址

其他文章

Vue3 + Vite + Ts开源后台管理系统模板


基于ElementUi或AntdUI再次封装基础组件文档


基于Element-plus再次封装基础组件文档(vue3+ts)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mpVue 微信小程序用户授权及wx.getUserProfile代替wx.getUserInfo获取用户信息及判断用户是否已经授权;不弹出微信授权窗口;只能使用头像、昵称填写能力 的相关文章

  • 如何理解区块链的运行原理?

    如何理解区块链的运行原理 上文 我们介绍了区块链的概念 今天就稍微深入一下 尽可能通俗地介绍一下 区块链的运行原理 通过上文的小故事 我们知道了区块链的概念 它的本质就是解决信任问题 降低信任成本的技术方案 目的就是为了去中心化 去信用中介
  • EasyUI Accordion 折叠面板默认不展示

    最近使用easyui做一套后台管理系统 左侧菜单使用的是Accordion折叠面板 需求是打开页面默认不展示子菜单 在网上找了一些博客 大多数都是说把 jquery easyui min js 中第多少行给注释了 我没有找到相应的代码 我使
  • Figma插件开发

    目的 介绍 Figma 插件 figma 插件开发从 0 到 1 分享自己开发的想法 一 Figma 是什么 figma 插件是什么 Figma 初印象 figma 是一个 基于浏览器 的协作式 UI 设计工具 figma 插件初印象 加强

随机推荐

  • 【解决方法】INF file txtsetup.sif is corrupt or missing

    今天帮别人装一个系统 一个上网本 先描述一下环境 上网本 没有光驱 只有一个分区 C 使用UltraISO制作的启动盘 所以 只能用U盘安装 或者说我只会 可是做好了启动盘之后安装确出现上面的问题 解决方法 使用WinSetupFromUS
  • kali下微信的使用dochat(盒装微信)

    一 dochat是什么 DoChat 盒装微信 是docker封装好的微信客户端 WeChat PC Windows Client for Linux 主要解决在linux下使用微信的问题 二 安装方法 官方介绍 GitHub huan d
  • 2023-9-14 石子合并

    题目链接 石子合并 include
  • Alibaba Druid简单介绍及使用

    文章目录 概要 Druid 的主要特点和功能 Druid 的使用 一 添加依赖 二 配置数据源 三 配置 Druid 监控和过滤器 四 启动应用程序 五 访问监控页面 小结 概要 Alibaba Druid 以下简称 Druid 是阿里巴巴
  • ppt to html5 sdk,kinvey-html5-sdk

    Kinvey JavaScript SDK for HTML5 applications Kinvey HTML5 SDK Installation From the command prompt go to your app s root
  • JavaObject类初识

    Java所有的类都继承Object类 Object类中的方法 Object类中的方法一般都需要重写 Sting toString 默认的 toString 返回的是对象的堆内存地址 重写 toString一般用于输出对象的属性 class
  • csdn测试

    测试
  • EasyPR编译指南

    1 下载源码 https github com liuruoze EasyPR Download ZIP或者git https github com liuruoze EasyPR git 将代码解压到硬盘目录下 例如F 车牌识别 Easy
  • Kotlin的一点学习资源

    本来想写一点Kotlin的文章的 后来看了一下它的中文文档 质量很不错 我再写就纯属浪费时间了 所以这里干脆整理一点Kotlin的学习资源吧 文档类 Kotlin官方网站 Kotlin官方文档 Kotlin中文网站 Kotlin中文文档 K
  • 达芬奇系列教程2-简单剪辑及一些快捷键

    达芬奇系列教程2 简单剪辑及一些快捷键 前言 一 初步设置 二 剪辑 1 步骤 2 剪辑面板功能键 3 剪辑 4 快编面板 5 字幕 三 快捷键 总结 前言 以下内容为 B站 影视飓风 达芬奇系列教程 文字版笔记 一 初步设置 1 创建面板
  • 【无标题】50hz IIR 滤波的实现

    使用fdatool Fs 依据采样率 Apass 选择衰减率 如果选为30db 即为衰减1000倍 并不是衰减率越高越好 而是够用就好 选择完毕后 按Design Filter 即可生成需要的IIR 50hz陷波器 在界面中也可以查看幅频特
  • python学习随笔

    打开文件管理器窗口方式 方式一 import subprocess 执行指令 explorer是windows文件管理器的指令 目录 subprocess Popen r explorer C Users dell Desktop hmui
  • 任意文件上传

    文章目录 渗透测试漏洞原理 任意文件上传 1 任意文件上传概述 1 1 漏洞成因 1 2 漏洞原理 1 3 漏洞危害 1 4 漏洞的利用方法 1 5 漏洞的验证 2 WebShell解析 2 1 Shell 2 1 1 命令解释器 2 2
  • 面试大闯关:自我介绍放大招

    It s the most feared question during any job interview Can you tell me about yourself Before I share a list of 10 memora
  • 掌握Python的X篇_9_关系运算符与逻辑运算符

    文章目录 1 True与False关键字 2 关系运算符 3 逻辑运算符 1 True与False关键字 Python中有True和False关键字 对应了生活中的 真 假 2 关系运算符 python中有以下的关系运算符 用于比较两个操作
  • 计算机专业毕业设计题目大全——各种类型系统设计大全

    计算机专业毕业设计题目大全 一 ASP类计算机专业毕业设计题目 1 网络留言薄 2 客户管理系统 3 多媒体积件管理库的开发与应用 4 基于WEB的多媒体素材管理库的开发与应用 5 网络教学软件中的教学设计与应用 6 小型教育网站的开发与建
  • [na]完全理解icmp协议

    1 ICMP出现的原因 在IP通信中 经常有数据包到达不了对方的情况 原因是 在通信途中的某处的一个路由器由于不能处理所有的数据包 就将数据包一个一个丢弃了 或者 虽然到达了对方 但是由于搞错了端口号 服务器软件可能不能接受它 这时 在错误
  • AndroidStudio Connection Reset 问题

    解决方案
  • 1012.数字分类- PAT乙级真题

    给定一系列正整数 请按要求对数字进行分类 并输出以下 5 个数字 A 1 能被 5 整除的数字中所有偶数的和 A 2 将被 5 除后余 1 的数字按给出顺序进行交错求和 A3 被 5 除后余 2 的数字的个数 A 4 被 5 除后余 3 的
  • mpVue 微信小程序用户授权及wx.getUserProfile代替wx.getUserInfo获取用户信息及判断用户是否已经授权;不弹出微信授权窗口;只能使用头像、昵称填写能力

    一 前言 2021年4月15日整改 为 优化用户的使用体验 平台将进行以下调整 1 2021年2月23日起 若小程序已在微信开放平台进行绑定 则通过wx login接口获取的登录凭证可直接换取unionID 2 2021年4月13日后发布的