思路: 通过uni-app文档可知:实现微信登录,无论是app还是小程序,都需要唯一标识openid,然后通过openid取掉后端的登录接口,获取cookie然后做登录跳转;

【-【-【必须先调用微信的登录接口uni.login() 然后再去调用授权按钮拿微信个人信息】-】-】
(否则顺序错乱会导致 小概率授权后拿不到头像和昵称)

可直接复制以下代码使用(替换下图片@/static/iconimg/wxtu.png):

需要注意91和115行代码注释,在那里调后端两个接口,分别获取openid和登录的cookie;

<template>
  <view class="page-login">
    <view v-if="canIUse||canIGetUserProfile">
      <view class='content'>
        <image style="width: 140rpx; height: 140rpx;" mode="aspectFit" src="@/static/iconimg/wxtu.png"></image>
        <view class="name">登录</view>
        <view>申请获取以下权限</view>
        <text>获得你的公开信息(昵称、头像、地区等)</text>
      </view>

      <view class="login-box">
        <!--新版登录方式-->
        <button v-if="canIGetUserProfile" class='login-btn' type='primary' @click="bindGetUserInfo"> 授权登录 </button>
        <!--旧版登录方式-->
        <button v-else class='login-btn' type='primary' open-type="getUserInfo" withCredentials="true" lang="zh_CN" @getuserinfo="bindGetUserInfo"> 授权登录 </button>

      </view>
    </view>
    <view v-else class="text-center">
      请升级微信版本
    </view>

  </view>
</template>
<script>
export default {
  data () {
    return {
      canIUse: uni.canIUse('button.open-type.getUserInfo'),
      canIGetUserProfile: false,//微信登录新旧版本 true是新
    }
  },
  onLoad () {
    //必须先调用微信的登录接口 然后再去调用授权拿微信个人信息(否则顺序错乱会导致 小概率授权后拿不到头像和昵称)
    this.wxLogin()
    var _this = this
    if (uni.getUserProfile) {
      this.canIGetUserProfile = true
    }
  },
  onShow () {

  },
  methods: {
    //登录授权
    bindGetUserInfo (e) {
      console.log('e', e)
      var _this = this
      if (this.canIGetUserProfile) {
        //新版登录方式
        uni.getUserProfile({
          desc: '获取您个人信息用于登录!',
          success: (res) => {
            console.log('用户信息', res)
            // 存入个人信息
            uni.setStorageSync('userInfo_winxin', res.userInfo)
            _this.updateUserInfo()
          },
          fail: (res) => {
            console.log(res)
          }
        })
      } else {
        //旧版登录方式 --自动就拉起授权窗口
        if (e.detail.userInfo) {
          //用户按了允许授权按钮
          //console.log('手动');
          console.log('老版用户信息', e.detail.userInfo)
          // 存入个人信息
          uni.setStorageSync('userInfo_winxin', e.detail.userInfo)
          _this.updateUserInfo()
        } else {
          console.log('用户拒绝了授权')
          //用户按了拒绝按钮
        }
      }
    },
    //登录---目的拿到code
    wxLogin () {
      let _this = this
      // 获取登录用户code
      uni.login({
        provider: 'weixin',
        success: function (res) {
          //console.log(res);
          if (res.code) {
            //将用户登录code传递到后台置换用户SessionKey、OpenId等信息 可参照此篇文章: https://ask.dcloud.net.cn/article/37452
            // 1.拿code调后端接口1 也就是getOpenid() 换取到SessionKey、OpenId(这个是唯一且固定不变)
            // 2.拿openId 调后端自己写的登录接口2  获取到cookie等信息 (这个cookie后期请求放在请求头上的) 登陆成功进行存储和跳转页面

            //这是我们的后端接口1--换取到SessionKey、OpenId
            // let params = { code: res.code}
            // getOpenid(params, false).then((res) => {
            //   console.log('拿code调后端接口1 换取到SessionKey、OpenId', res)
            //   uni.setStorageSync('session_key', res.data.session_key)
            //   uni.setStorageSync('openid', res.data.openid)
            // })
          } else {
            uni.showToast({ title: '获取logon_code失败', duration: 2000 })
            console.log('获取logon_code失败' + res.errMsg)
            _this.wxLogin()
          }
        },
        fail: (res) => {
          uni.showToast({ title: '获取logon_code失败', duration: 2000 })
          console.log('获取logon_code失败' + res.errMsg)
          _this.wxLogin()
        }
      })
    },
    //向后台更新信息
    updateUserInfo () {
      let _this = this

      //这是我们的后端接口2--登录接口2  获取到cookie等信息(这个cookie后期请求放在请求头上的)
      // let params = {
      //   openid: uni.getStorageSync('openid'),
      //   nickname: uni.getStorageSync('userInfo_winxin').nickName,
      //   head_image: uni.getStorageSync('userInfo_winxin').avatarUrl,
      // }
      // loginByWechat(params).then((res) => {

      // })

      //下面的这个cookie键值对是暂时写死的,正常应该接口2返回的
      let login_cookie_name = 'login_cookie_name'
      let login_cookie_value = 'login_cookie_value'
      uni.setStorageSync('login_cookie_name', login_cookie_name)
      uni.setStorageSync('login_cookie_value', login_cookie_value)
      // 注意:以上的存储为了在request请求时候携带和判断用  在退出登录时候需要清除掉

      uni.hideLoading()
      uni.showToast({
        title: '接口登录逻辑自写-登陆成功',
        duration: 1500,
        icon: 'success',
      })
      // 跳转到首页
      uni.reLaunch({ url: '/pages/index/index' })

    }
  }
}
</script>

<style lang="less" scoped>
.content {
  text-align: center;
}
</style>

但是获取openid的方式不同,目前有两个方式获取到。

注意一: 获取openid

1.通过uni.login()方法,得到code,拿这个code调用后端写的接口获取openid(此方式微信小程序和app都支持,H5不支持);如何通过code换取 session 和 openid/unionid

2.app还可以通过uni.getUserInfo 直接获取到openid

注意2: 获取用户信息方法有两种

1.需要注意,uni.getUserInfo是旧方法,它不支持新的版本,在新版本小程序里使用获取到的是默认信息无效的; 微信小程序端,在用户未授权过的情况下调用此接口,不会出现授权弹窗,会直接进入 fail 回调。在用户已授权的情况下调用此接口,可成功获取用户信息。

2.推荐使用uni.getUserProfile新的获取用户方法;每次请求都会弹出授权窗口,用户同意后返回 userInfo。

这张图是微信官方更新日志:

uniapp ios微信调试 调试工具 uniapp调用微信登录_uni-app微信登录app

获取appId和AppSecret:

uniapp ios微信调试 调试工具 uniapp调用微信登录_uni-app微信登录app_02

获取code方法:

uniapp ios微信调试 调试工具 uniapp调用微信登录_uniapp ios微信调试 调试工具_03


获取用户信息的两个方法

uniapp ios微信调试 调试工具 uniapp调用微信登录_uni-app微信登录_04

uniapp ios微信调试 调试工具 uniapp调用微信登录_微信登录_05