亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > PHP > 正文

PHP實現微信小程序用戶授權的工具類示例

2024-05-05 00:07:09
字體:
來源:轉載
供稿:網友

先準備工作

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=" + 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?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code',config('param.wxa_user_info_session_key_url'),$appid,$appsecret,$code);    $rtnJson = curlRequest($sessionKeyUrl);    $data = json_decode($rtnJson,true);    error_log('authorization wx return data========>');    error_log($rtnJson);    if(isset($data['errcode'])){      return $data;    }    $sessionKey = $data['session_key'];    $wxHelper = new WxBizDataHelper($appid,$sessionKey,$encryptedData,$iv);    $data['errcode'] = 200;    $data['data'] = [];    if(!$wxData = $wxHelper->getData()){      $data['errcode'] = -1;    }else{      error_log('current wx return data is =========>'.json_encode($wxData));      $data['data'] = $wxData;    }    return $data;  }

保存用戶信息的方法

 /**   * 保存用戶信息的方法   * @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'])?$accountData['avatar']:"",          'from_appid' => $accountData['from_appid'],          'province' => $wxaUserData['province'],          'city' => $wxaUserData['city'],          'country' => $wxaUserData['country'],          'openid' => $wxaUserData['openId'],          'wx_header' => isset($wxaUserData['avatarUrl'])?$wxaUserData['avatarUrl']:"",          'gh_openid' => $regFromGh?$wxaUserData['openId']:"",        ];        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工具類

<?php/** * Created by PhpStorm. * User: Auser * Time: 11:17 */namespace App/Http/Base/Wx;class WxBizDataHelper{  private $appid;  private $seesionKey ;  private $encryptedData;  private $iv;  public function __construct($appid, $sessionKey,$encryptedData, $iv)  {    $this->appid = $appid;    $this->seesionKey = $sessionKey;    $this->encryptedData = $encryptedData;    $this->iv = $iv;  }  public function getData(){    $pc = new WXBizDataCrypt($this->appid, $this->seesionKey);    $json = '';    $errCode = $pc->decryptData($this->encryptedData, $this->iv, $json);    $data = [];    if ($errCode == 0) {      $data = json_decode($json,true);    }    return $data;  }}

WXBizDataCrypt工具類

<?php/** * Created by PhpStorm. * User: Auser * Time: 10:38 */namespace App/Http/Base/Wx;use App/Http/Base/Wx/Prpcrypt;use App/Http/Base/Wx/ErrorCode;use App/Http/Base/Wx/PKCS7Encoder;class WXBizDataCrypt{  private $appid;  private $sessionKey;  /**   * 構造函數   * @param $sessionKey string 用戶在小程序登錄后獲取的會話密鑰   * @param $appid string 小程序的appid   */  public function __construct( $appid, $sessionKey)  {    $this->sessionKey = $sessionKey;    $this->appid = $appid;  }  /**   * 檢驗數據的真實性,并且獲取解密后的明文.   * @param $encryptedData string 加密的用戶數據   * @param $iv string 與用戶數據一同返回的初始向量   * @param $data string 解密后的原文   *   * @return int 成功0,失敗返回對應的錯誤碼   */  public function decryptData( $encryptedData, $iv, &$data )  {    if (strlen($this->sessionKey) != 24) {      return ErrorCode::$IllegalAesKey;    }    $aesKey=base64_decode($this->sessionKey);    if (strlen($iv) != 24) {      return ErrorCode::$IllegalIv;    }    $aesIV=base64_decode($iv);    $aesCipher=base64_decode($encryptedData);    $pc = new Prpcrypt($aesKey);    $result = $pc->decrypt($aesCipher,$aesIV);    if ($result[0] != 0) {      return $result[0];    }    $dataObj=json_decode( $result[1] );    if( $dataObj == NULL )    {      return ErrorCode::$IllegalBuffer;    }    if( $dataObj->watermark->appid != $this->appid )    {      return ErrorCode::$IllegalBuffer;    }    $data = $result[1];    return ErrorCode::$OK;  }}

Prpcrypt工具類

<?php/** * Created by PhpStorm. * User: Auser * Time: 10:55 */namespace App/Http/Base/Wx;class Prpcrypt{  public $key;  public function __construct($key)  {    $this->key = $key;  }  /**   * 對密文進行解密   * @param string $aesCipher 需要解密的密文   * @param string $aesIV 解密的初始向量   * @return string 解密得到的明文   */  public function decrypt($aesCipher, $aesIV)  {    try {      $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');      mcrypt_generic_init($module, $this->key, $aesIV);      //解密      $decrypted = mdecrypt_generic($module, $aesCipher);      mcrypt_generic_deinit($module);      mcrypt_module_close($module);    } catch (Exception $e) {      return array(ErrorCode::$IllegalBuffer, null);    }    try {      $result = PKCS7Encoder2::decode($decrypted);    } catch (Exception $e) {      //print $e;      return array(ErrorCode::$IllegalBuffer, null);    }    return array(0, $result);  }}

ErrorCode狀態代碼類

<?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;}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日在线观看| 91亚洲午夜在线| 91影院在线免费观看视频| 国产精品影片在线观看| 日韩第一页在线| 亚洲人成在线播放| 国产玖玖精品视频| 日韩免费av片在线观看| 国产成人午夜视频网址| 精品免费在线视频| 日韩在线免费视频观看| 国产精品激情av电影在线观看| 色偷偷88888欧美精品久久久| 亚洲精品久久久久久久久久久| 性色av一区二区三区在线观看| 亚洲精品欧美一区二区三区| 91香蕉嫩草影院入口| 国产精品三级美女白浆呻吟| 91欧美精品午夜性色福利在线| 夜夜嗨av一区二区三区四区| 亚洲国产精品国自产拍av秋霞| 亚洲一区精品电影| 性色av一区二区三区红粉影视| 亚洲国产精品成人一区二区| 亚洲人成毛片在线播放| 欧美午夜电影在线| 亚洲高清久久久久久| 国产精品偷伦免费视频观看的| 91老司机精品视频| 日韩av免费在线| 国产免费成人av| 精品久久久久久久中文字幕| 日韩中文字幕视频| 69视频在线播放| 日韩av电影国产| 日韩欧美中文第一页| 欧美丰满片xxx777| 欧美亚洲一区在线| 北条麻妃在线一区二区| 欧美日韩亚洲91| 国产精品看片资源| 国产精品视频导航| 日韩免费av一区二区| 一级做a爰片久久毛片美女图片| 亚洲精品欧美日韩专区| 精品高清一区二区三区| 日韩精品极品在线观看播放免费视频| 久久综合伊人77777蜜臀| 91国内揄拍国内精品对白| 国产九九精品视频| 久久精品国产成人精品| 成人性生交大片免费看视频直播| 国产精品一区=区| 2019中文字幕在线免费观看| 成人在线播放av| 欧美成年人视频网站| 日韩欧美极品在线观看| 亚洲乱码国产乱码精品精| 日韩精品免费观看| 欧美日韩中文字幕日韩欧美| 国产91精品视频在线观看| 日韩成人在线免费观看| 日韩精品免费一线在线观看| 国产免费观看久久黄| 亚洲www在线观看| 欧美大全免费观看电视剧大泉洋| 日韩亚洲综合在线| 成人黄色免费在线观看| 欧美午夜无遮挡| 一本大道香蕉久在线播放29| 91高清视频在线免费观看| 热久久99这里有精品| 国产国语刺激对白av不卡| 久久精品成人一区二区三区| 26uuu亚洲国产精品| 上原亚衣av一区二区三区| 一区二区三区视频在线| 精品国产区一区二区三区在线观看| 久久久久久久久中文字幕| 精品久久久久久久中文字幕| 国内免费久久久久久久久久久| 亚洲精品中文字幕女同| 久久国产精品久久久久久久久久| 日韩在线视频线视频免费网站| 曰本色欧美视频在线| 日韩av最新在线观看| 91av视频在线播放| 日本亚洲欧洲色α| 一本一本久久a久久精品综合小说| 午夜精品久久久久久99热| 亚洲欧美精品一区二区| 伊人伊成久久人综合网站| 国产日韩欧美91| 91精品国产高清久久久久久91| 日本亚洲欧美三级| 亚洲天堂av图片| 亚洲三级免费看| 亚洲中国色老太| 亚洲精品国产成人| 91成人天堂久久成人| 午夜精品免费视频| 国产精品爽爽ⅴa在线观看| 精品中文字幕视频| 久久激情视频久久| 97超级碰碰碰久久久| 最新国产精品拍自在线播放| 亚洲第一中文字幕在线观看| 欧美在线激情网| 亚洲va欧美va在线观看| 亚洲欧美资源在线| 亚洲电影天堂av| 国产精品高清网站| 欧美日本高清一区| 久久久久久久久久亚洲| 亚洲电影免费观看高清| 日韩av免费网站| 欧美日韩色婷婷| 欧美激情手机在线视频| 亚洲国产精品一区二区久| 亚洲成人激情图| 国产国产精品人在线视| 日韩高清电影免费观看完整| 亚洲色图日韩av| 成人免费在线网址| 欧美日韩一区二区三区在线免费观看| 国产一区二区在线播放| 国产成人啪精品视频免费网| 国产精品视频一区国模私拍| 久久精品亚洲一区| 欧美资源在线观看| 欧美激情视频在线观看| 久久免费精品日本久久中文字幕| 欧美大片大片在线播放| 国产日韩欧美日韩大片| 久久精品2019中文字幕| 亚洲精品国产精品国自产在线| 国内免费精品永久在线视频| 日韩的一区二区| 成人欧美一区二区三区在线| 一二美女精品欧洲| 亚洲精品日韩久久久| 亚洲精品v欧美精品v日韩精品| 国内精品免费午夜毛片| 国产精品久久久久av| 亚洲视频日韩精品| 亚洲欧美国内爽妇网| 亚洲国产女人aaa毛片在线| 欧美一区二区影院| 国产精品极品美女粉嫩高清在线| 久久久久久午夜| 国产欧美精品一区二区三区介绍| 91亚洲精品在线观看| 性欧美xxxx视频在线观看| 亚洲图中文字幕| 精品欧美一区二区三区| 5252色成人免费视频| 欧美最顶级的aⅴ艳星| 日韩激情视频在线播放| 91在线高清视频| 国产精品久久久久久久久借妻| 成人免费视频网址| 91精品国产自产在线老师啪| 日韩av免费在线播放| 中文字幕免费精品一区高清|