网上找了很多教程都不好使,最后自己又研究了一番,终于成功了

一、总体设计

小程序登录流程:客户端通过调用wx.login(),获取登录凭证(code),将此code发往服务器,服务器通过调用 auth.code2Session 接口,使用 code 换取 openid、unionid、session_key 等信息。

参考官方给出的时序图:

本实例中将openid作为用户唯一标识,存入数据库中。服务器后端通过ThinkPHP框架实现两个接口:

http://localhost/srclib/index.PHP/Home/User/wxlogin // 登录接口
http://localhost/srclib/index.PHP/Home/User/wxsign // 首次登录(微信授权登录)接口

1. 登录状态的维持

小程序在初始化时,在小程序onLaunch生命周期函数中调用wx.login(),向登录接口发送请求,将code发送给服务器。服务器接收到code后,调用https://api.weixin.qq.com/sns/jscode2session接口,将code,appid和appSecret发送给微信官方服务器,服务器会收到用户唯一标识openid和会话密钥 session_key等信息。

此时服务器后台在数据库User表中查询openid:

  • 如果在User表中没有查到该记录,则说明此用户是新用户,还未授权微信登录,服务器返回客户端的状态码err_code值为1,表示不存在该用户,需要用户手动授权微信登录;

  • 如果在User表中查到了该记录,则表示用户已授权微信登录,此时服务器返回客户端的状态码err_code值为0,表示登录成功,服务器将用户信息和状态码发送至前端。

客户端在接收到状态码后判断:

  • 若状态码为0,则表示登录成功。客户端接收到用户信息后,通过调用wx.setStorageSync()将用户信息加入本地缓存,并将登录状态设置为true,此时实现了登录状态的维持;

  • 若状态码为1,表示用户还未授权登录,此时跳转至auth页等待用户的授权操作。

首次授权后,小程序每次启动时,自动调用登录接口,并将在本地缓存中更新用户信息和登录状态,小程序其他页面在初始化时调用_initial()函数,从本地缓存中取出用户信息和登录状态,赋值给全局变量userInfo和loginState,此后小程序页面渲染时便可从全局变量获取用户信息,设置给页面对象的data属性值。

2. 微信授权登录的实现

微信官方提供了wx.getUserProfile接口,使用获取用户信息。在页面中加入一个button,监听用户点击,点击后获取用户信息,本实例中主要获取了用户昵称nickName和用户头像地址avatarUrl。之后向(微信授权登录)首次登录接口发送请求,输入数据为code、nickName和avatarUrl。

服务端接收到这些参数后,首先调用https://api.weixin.qq.com/sns/jscode2session接口,将code,appid和appSecret发送给微信官方服务器,服务器会收到用户唯一标识openid等参数,然后在数据库User表中查询该openid:

  • 如果在User表中没有查到该记录,则将openid、nickName和avatarUrl构建为一条用户记录数据,插入User表中,服务器返回客户端的状态码err_code值为0,表示新用户授权登录成功,服务器将用户信息和状态码发送至前端;

  • 如果在User表中查到了该记录,则表示该用户重复授权,抛出异常,此时服务器返回客户端的状态码err_code值为1。

二、步骤说明

1. 用户首次进入,显示授权登录按钮

2. 点击授权登录按钮,出现提示弹窗

3. 点击允许后,登录成功,跳转至个人中心页

4. 此后用户再次进入小程序,已自动登录,实现了登录状态的维持

三、完整代码:

1. 小程序前端:

app.js

// app.js
App({
  globalData: {
    loginState: false, // 用户登录状态
    userInfo: null // 用户信息
  },
  onLaunch() {
    this.login() // 登录
  },
  _initial() { // Page初始化函数,用于读取本地缓存,并更新全局变量
    this.globalData.userInfo = wx.getStorageSync('userInfo')
    this.globalData.loginState = wx.getStorageSync('loginState')
    console.log("登录状态:"+this.globalData.loginState)
    console.log("用户信息:")
    console.log(this.globalData.userInfo)
  },
  login() {
    let _this = this
    // 登录请求
    wx.login({
      success: res => {
        wx.request({
          url: 'http://localhost/srclib/index.PHP/Home/User/wxlogin',
          method: 'post',
          data: {
            code: res.code
          },
          header: {
            "Content-Type": "application/x-www-form-urlencoded"
          },
          success: function (res) {
            if(res.data.error_code == 1) { // 用户未授权登录
              console.log("error")
              wx.setStorageSync('loginState', false)
              wx.navigateto({ // 跳转至授权页,等待用户授权
                url: '../auth/auth', 
              })
            } else if(res.data.error_code == 0) { // 登录成功
              wx.setStorageSync('userInfo', res.data.data) // 更新本地缓存
              wx.setStorageSync('loginState', true)
            }
          }
        })
      }
    })
  }
})

profile.js

// pages/profile/profile.js
const app = getApp()
const globalData = getApp().globalData
Page({
  data: {
    userInfo: null
  },
  onl oad() {
    app._initial() // 页面初始化
    this.setData({
      userInfo: globalData.userInfo
    })
  }
})

auth.js

// auth.js
const app = getApp()
const globalData = getApp().globalData
Page({
  data: {
    userInfo: null
  },
  onl oad() {
    app._initial() // 页面初始化
  },
  getUserProfile(e) {
    // 使用wx.getUserProfile获取用户信息
    wx.getUserProfile({
      desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中
      success: (res) => {
        globalData.userInfo = res.userInfo
        this.setData({
          userInfo: globalData.userInfo
        })
        this.sign()
      }
    })
  },
  sign() {
    let _this = this
    wx.showLoading({
      title: '加载中',
    })
    // 用户首次登录请求
    wx.login({
      success: res => {
        wx.request({
          url: 'http://localhost/srclib/index.PHP/Home/User/wxsign',
          method: 'post',
          data: {
            code: res.code,
            name: globalData.userInfo.nickName,
            avatarUrl: globalData.userInfo.avatarUrl
          },
          header: {
            "Content-Type": "application/x-www-form-urlencoded"
          },
          success: function (res) {
            if(res.data.error_code == 1) { // 用户登录失败
              console.log("error")
            } else if(res.data.error_code == 0) { // 用户登录成功
              wx.setStorageSync('userInfo', res.data.data) // 更新本地缓存
              wx.setStorageSync('loginState', true)
              wx.hideLoading()
              wx.showToast({
                title: '授权成功',
                icon: 'success',
                duration: 2000,
                complete: (res) => {
                  wx.navigateto({ // 跳转至个人中心页
                    url: '../profile/profile',
                  })
                },
              })
            }
          }
        })
      }
    })
  }
})

profile.wxml

<!--pages/profile/profile.wxml-->
<view>
<view>
    <image bindtap="bindViewTap"src="{{userInfo.face_url}}" mode="cover"></image>
    <text>{{userInfo.username}}</text>
  </view>
  <viewhttps://www.www.95094.com/tag/ott/" target="_blank">otto">
    <texthttps://www.www.95094.com/tag/ott/" target="_blank">otto">{{loginState}}</text>
  </view>
</view>

auth.wxml

<!--auth.wxml-->
<view>
  <button type="primary" bindtap="getUserProfile">授权微信登录</button>
</view>

2. 服务器后端

<?PHP
namespace Home\Controller;
use Think\Controller;
class UserController extends BaseController
{
    /**
     * 微信登录
     * @return [type] [description]
     */
    public function wxlogin()
    {
        // 校验参数是否存在
        if (!$_POST['code']) {
            $return_data = array();
            $return_data['error_code'] = 2;
            $return_data['msg'] = '参数不足: code';
            $this->ajaxReturn($return_data);
        } else {
            $appid = "wxc6a376950e1c45c0"; // appid
            $secret = "632hjdcba4c2b972c591738hdga91fvg"; // app密钥
            $code = $_POST['code']; // 小程序传来的code值
            $curl = curl_init();
            $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $appid . "&secret=" . $secret . "&js_code=" . $code . "&grant_type=authorization_code";
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $result = curl_exec($curl);
            $json = json_decode($result); // 对json数据解码
            $arr = get_object_vars($json);
            $openid = $arr['openid'];
            curl_close($curl);
            // 检验是否已经注册
            $User = M('User');
            // 构造查询条件
            $where = array();
            $where['openid'] = $openid;
            $user = $User->where($where)->find();
            if ($user) {
                $return_data = array();
                $return_data['error_code'] = 0;
                $return_data['msg'] = '登录成功';
                $return_data['data']['userid'] = $user['userid'];
                $return_data['data']['username'] = $user['username'];
                $return_data['data']['face_url'] = $user['face_url'];
                $this->ajaxReturn($return_data);
            } else {
                $return_data = array();
                $return_data['error_code'] = 1;
                $return_data['msg'] = '不存在该用户,请授权登录';
                $this->ajaxReturn($return_data);
            }
        }
    }

    /**
     *首次授权登录
     * @return [type] [description]
     */
    public function wxsign()
    {
        // 校验参数是否存在
        if (!$_POST['code']) {
            $return_data = array();
            $return_data['error_code'] = 2;
            $return_data['msg'] = '参数不足: code';
            $this->ajaxReturn($return_data);
        } else if (!$_POST['name']) {
            $return_data = array();
            $return_data['error_code'] = 2;
            $return_data['msg'] = '参数不足: name';
            $this->ajaxReturn($return_data);
        } else if (!$_POST['avatarUrl']) {
            $return_data = array();
            $return_data['error_code'] = 2;
            $return_data['msg'] = '参数不足: avatarUrl';
            $this->ajaxReturn($return_data);
        } else {
            $appid = "wxc6a376950e1c45c0"; // appid
            $secret = "632hjdcba4c2b972c591738hdga91fvg"; // app密钥
            $code = $_POST['code']; // 小程序传来的code值
            $curl = curl_init();
            $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $appid . "&secret=" . $secret . "&js_code=" . $code . "&grant_type=authorization_code";
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $result = curl_exec($curl);
            $json = json_decode($result); // 对json数据解码
            $arr = get_object_vars($json);
            $openid = $arr['openid'];
            curl_close($curl);
            // 检验是否已经授权过
            $User = M('User');
            // 构造查询条件
            $where = array();
            $where['openid'] = $openid;
            $user = $User->where($where)->find();
            if ($user) {
                $return_data = array();
                $return_data['error_code'] = 1;
                $return_data['msg'] = '登录失败';
                $this->ajaxReturn($return_data);
            } else {
                // 如果用户尚未注册,则注册
                // 构建插入的数据 
                $data = array();
                $data['openid'] = $openid;
                $data['username'] = $_POST['name'];
                $data['face_url'] = $_POST['avatarUrl'];
                // 插入数据
                $result = $User->add($data);
                // add数据添加成功之后,返回的就是该条数据的id
                if ($result) {
                    // 插入数据执行成功
                    $return_data = array();
                    $return_data['error_code'] = 0;
                    $return_data['msg'] = '登录成功';
                    $return_data['data']['userid'] = $result;
                    $return_data['data']['username'] = $_POST['name'];
                    $return_data['data']['face_url'] = $_POST['avatarUrl'];
                    $this->ajaxReturn($return_data);
                } else {
                    // 插入数据执行失败
                    $return_data = array();
                    $return_data['error_code'] = 1;
                    $return_data['msg'] = '登录失败';
                    $this->ajaxReturn($return_data);
                }
            }
        }
    }
}

uni-app 微信小程序授权登录的实现步骤

uni-app 微信小程序授权登录的实现步骤

一、appID相关申请和配置

1. appid获取方式

登录微信公众平台

官网链接:https://mp.weixin.qq.com/

第一次需要小伙伴们点击注册按钮,进行注册,如果有账号,直接扫描登录即可

官网小程序链接:

2. appID配置

在manifest.json中输入申请的微信小程序id

二、获取用户基础数据

这里给小伙伴们演示二种api

2.1. 获取用户信息

可以使用uni.getUserProfile请求用户授权获取用户信息, 也可以使用uni.getUserInfo获取

授权成功后获取到的用户信息在userInfo中:

页面部分:

js部分:

获取的用户基础数据(无openid=》微信用户唯一标识)

2.2. 获取用户信息2

可以使用uni.getUserInfo请求用户授权获取用户信息

页面一样,js部分:

获取的用户基础数据(无openid=》微信用户唯一标识)

总结:uni.getUserProfile和uni.getUserInfo 二个api获取的用户数据基本一样,都无openid=》微信用户唯一标识。

三、调用登录api

3.1. 登录api

使用uni.login方法,provider参数输入’weixin’,成功的返回值中如果errMsg=“login:ok” 代表成功,
微信小程序端会返回一个code字符串

3.2. 案例代码

四、获取唯一标识信息

4.1. 官网文档

官网文档
使用获取到的code请求微信登录接口,获取 openid 和 session_key

4.2. 接口简述

请求方式:GET
APPID:小程序唯一标识,上面有获取方式
SECRET:小程序唯一标识的秘钥,上面参考APPID获取方式,就在他的下面
JSCODE:这个前端调用  uni.login获取

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

五、绑定用户 实现登录

获取到微信用户的唯一id后,就可以绑定至自己系统中的用户,我的做法是在用户表中加入weixinId字段,跳转至自己的用户绑定界面,如果用户选择绑定微信,则更新该行用户数据的weixinId。下次用户使用微信登录时,如果通过openId能够查询到一条用户数据,说明已经绑定,则登录该用户

5.1. 代码案例(未封装)

前端部分:

后端部分

5.2. 代码案例(封装)

user.js

vuex user模块(user.js)

六、项目开源地址

6.1. 前端

applet-chock-in

6.2. 后端

weixin-java-miniapp

今天关于微信小程序unionid获取问题微信小程序 unionid openid的介绍到此结束,谢谢您的阅读,有关.NET之微信小程序获取用户UnionID、php实现微信小程序授权登录功能(实现流程)、ThinkPHP实现微信小程序微信授权登录、uni-app 微信小程序授权登录的实现步骤等更多相关知识的信息可以在本站进行查询。

本文标签: