先准备工作

1.申请一个小程序,申请地址:传送门
2.仔细阅读小程序的用户授权登陆官方文档: 《用户授权登陆的流程》
3.仔细阅读微信用户数据解密的相关文档: 《用户数据解密说明文档》
4.在小程序后台配置好相应的后端请求地址,路径是:开发---->开发设置,如图

PHP实现微信小程序用户授权的工具类示例

5.小程序如果需要做多个小程序的打通,还需要在微信开放平台绑定到开发者账号下面, 如果不需要union_id请忽略

6.服务端准备一个用户授权的接口,假设接口链接为http://test.dev.com/user/authorization,此接口接受如下参数

  • code:微信登陆接口返回的登陆凭证,用户获取session_key
  • iv:微信小程序登陆接口返回的向量,用于数据解密
  • encrypted_data : 微信获取用户信息接口的返回的用户加密数据,用于后端的接口解析
  • signature加密数据

接口返回的数据如下

{
  "errcode": 200,
  "msg": "SUCCESS",
  "data": {
    "uid": 34098,
    "unionid": "xxx",
  }
}

6.建表

1)用户表,其中比较重要的字段是union_id,因为我们是有多个小程序和公众号,因此使用这个来区分唯一的用户编号

DROP TABLE IF EXISTS `jz_wxa_user`;
CREATE TABLE `jz_wxa_user` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `uid` bigint(18) DEFAULT NULL,
 `openid` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT 'openid',
 `user_name` varchar(100) CHARACTER SET utf8mb4 DEFAULT '',
 `nick_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '用户昵称',
 `sex` enum('0','1') CHARACTER SET utf8 DEFAULT '1' COMMENT '性别',
 `avatar` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '用户头像',
 `province` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '省份',
 `city` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '城市',
 `country` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '国家',
 `wx_union_id` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '公众平台的唯一id',
 `from_url` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '来源url',
 `created_at` timestamp NULL DEFAULT NULL,
 `updated_at` timestamp NULL DEFAULT NULL,
 `from_appid` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT 'wx95fc895bebd3743b' COMMENT '来源appid',
 `wx_header` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '微信头像',
 `gh_openid` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '微信公众号openid',
 `phone` varchar(30) CHARACTER SET utf8 DEFAULT '' COMMENT '手机号码',
 PRIMARY KEY (`id`),
 KEY `idx_uid_union_id` (`uid`,`wx_union_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

实现步骤

用户授权时序图

PHP实现微信小程序用户授权的工具类示例

关键代码

小程序端

小程序端的获取用户信息流程

1)调用login方法获取code
2)调用getUserInfo方法获取用户的加密数据
3)调用后端的用户授权接口将用户信息保存到服务端
4)保存后端接口返回的uid和unionid到localstorage中,作为全局参数

获取用户的授权信息

getUid:function(cf){
  var that = this
  wx.login({
   success: function (ress) {
    var code = ress.code 
    wx.getUserInfo({ 
     withCredentials: true,     
     success: function (res) {
      that.globalData.userInfo = res.userInfo;
      that.authorize(code, res.signature, res.iv, res.rawData, res.encryptedData, cf)
     }
    })
   }
  })
 },
 authorize: function (code, signature, iv, rawData, encryptedData, cf) {
  var that =this
  var dataobj = {
   code: code,
   signature: signature,
   iv: iv,
   raw_data: rawData,
   encrypted_data: encryptedData
  }
  console.log("code:",code)
  var param = JSON.stringify(dataobj)
  param = that.Encrypt(param)
  var url = that.data.API_DOMAIN2 + "/user/authorization" + param
  wx.request({
   url: url,
   method: "GET",
   header: {
    'content-type': 'application/json'
   },
   success: function (res) {
    if (res.data.errcode == 200) {
     wx.hideToast()    
     wx.setStorage({
      key: "uid",
      data: res.data.data.uid,
      success: function () {
       if (cf) {
        typeof cf == "function" && cf(res.data.data.uid)
       }
      }
     })
    } else {
     that.exceptionHandle('uid', url, res.data.errcode, res.data.msg)
    }
   }
  })
 },

服务端

入口方法

/**
   * api接口开发
   * 获取详情的接口
   * @param $uid 用户编号
   * @param $iv 向量
   * @param $encryptedData 微信加密的数据
   * @param $rawData 判断是否为今天
   * @param $signature 签名
   * @return array
   */
  public static function authorization($appid,$appsecret,$code,$iv,$encryptedData,$rawData,$signature){
    $result = self::decodeWxData($appid,$appsecret,$code,$iv,$encryptedData);
    if($result['errcode'] != 200){
      return $result;
    }
    //处理微信授权的逻辑
    $wxUserData = $result['data'];
    error_log("authorization data=============>");
    error_log(json_encode($wxUserData));
    $uid = WxaUserService::regWxaUser($wxUserData);
    $data['uid'] = $uid['uid'];
    $data['unionid'] = $uid['unionid'];
    $result['data'] = $data;
    return $result;
  }
  
  /**
   * 解密微信的数据
   * @param $code wx.login接口返回的code
   * @param $iv wx.getUserInfo接口或者wx.getWeRunData返回的iv
   * @param $encryptedData wx.getUserInfo接口或者wx.getWeRunData返回的加密数据
   * @return array
   */
  public static function decodeWxData($appid,$appsecret,$code,$iv,$encryptedData){
    $sessionKeyUrl = sprintf('%s"htmlcode">
 /**
   * 保存用户信息的方法
   * @param $wxaUserData
   * @param $regFromGh 表示是否从公众号进行注册
   */
  public function regWxaUser($wxaUserData,$regFromGh = false)
  {
    $value = $wxaUserData['unionId'];
    $key = getCacheKey('redis_key.cache_key.zset_list.lock') . $value;
    $newExpire = RedisHelper::getLock($key);
    $data = $this->storeWxaUser($wxaUserData,$regFromGh);
    RedisHelper::releaseLock($key, $newExpire);
    return $data;
  }
  
  /**
   * 保存信息
   * @param $wxaUserData
   * @return mixed
   */
  public function storeWxaUser($wxaUserData,$regFromGh = false)
  {
    $wxUnionId = $wxaUserData['unionId'];
    if (!$user = $this->getByWxUnionId($wxUnionId)) {
      $getAccountDataStartTime = time();
      //这里是因为需要统一账户获取uid,所以这个是用户中心的接口,如果没有这个流程,则直接使用数据
      if($accountData = AccountCenterHelper::regWxaUser($wxaUserData)){
        $getAccountDataEndTime = time();
        $accountRegTime = $getAccountDataEndTime - $getAccountDataStartTime;
        error_log("reg user spend time is ===================>" . $accountRegTime);
        $user = [
          'uid' => $accountData['uid'],
          'user_name' => $accountData['user_name'],
          'nick_name' => $wxaUserData['nickName'],
          'sex' => $accountData['sex'],
          'wx_union_id' => $accountData['wx_union_id'],
          'avatar' => isset($accountData['avatar'])"",
          'from_appid' => $accountData['from_appid'],
          'province' => $wxaUserData['province'],
          'city' => $wxaUserData['city'],
          'country' => $wxaUserData['country'],
          'openid' => $wxaUserData['openId'],
          'wx_header' => isset($wxaUserData['avatarUrl'])"",
          'gh_openid' => $regFromGh"",
        ];
        error_log("insert data=============>" . json_encode($user));
        $user = $this->store($user);
        $regApiUserEndTime = time();
        error_log(" reg api user spend time================>" . ($regApiUserEndTime - $getAccountDataEndTime));
        error_log(" after insert data=============>" . json_encode($user));
      }
    }else{
      if(!$user['wx_header']){
        $updateData = [
          'id' => $user['id'],
          'uid' => $user['uid'],
          'wx_header' => $wxaUserData['avatarUrl'],
        ];
        $this->update($updateData);
      }
      //同步用户的openid
      if($wxaUserData['openId'] != $user['openid']){
        $updateData = [
          'id' => $user['id'],
          'uid' => $user['uid'],
          'openid' => $wxaUserData['openId'],
        ];
        $this->update($updateData);
      }
    }
    $data['uid'] = $user['uid'];
    $data['unionid'] = $wxUnionId;
    return $data;
  }

根据unionid获取用户信息

  /**
   * 根据unionid获取用户信息
   */
  public function getByWxUnionId($unionId)
  {
    $cacheKey = getCacheKey('redis_key.cache_key.wxa_user.info') . $unionId;
    $value = $this->remember($cacheKey, function () use ($unionId) {
      $userInfo = WxaUser::where('wx_union_id', $unionId)->first();
      $userInfo = $this->compactUserInfo($userInfo);
      return $userInfo;
    });
    return $value;
  }

WxBizDataHelper工具类

<"htmlcode">
<"htmlcode">
<"htmlcode">
<?php
/**
 * Created by PhpStorm.
 * User: Auser
 * Time: 10:33
 */

namespace App\Http\Base\Wx;


class ErrorCode
{
  public static $OK = 0;
  public static $IllegalAesKey = -41001;
  public static $IllegalIv = -41002;
  public static $IllegalBuffer = -41003;
  public static $DecodeBase64Error = -41004;

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!

P70系列延期,华为新旗舰将在下月发布

3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。

而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?

根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。