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

事先準備工作

1.申請一個小程序,申請地址: 傳送門

2.仔細閱讀小程序的用戶授權登陸官方文檔: 《用戶授權登陸的流程》

3.仔細閱讀微信用戶數據解密的相關文檔: 《用戶數據解密說明文檔》

4.在小程序後臺配置好相應的後端請求地址,路徑是:開發---->開發設置,如圖

5.小程序如果需要做多個小程序的打通,還需要在 微信開放平臺 綁定到開發者賬號下面, 如果不需要union_id請忽略

6.服務端準備一個用戶授權的接口,假設接口鏈接爲 http://test.dev.com/user/auth... ,此接口接受如下參數

  • code:微信登陸接口返回的登陸憑證,用戶獲取session_key
  • iv:微信小程序登陸接口返回的向量,用於數據解密
  • encrypted_data : 微信獲取用戶信息接口的返回的用戶加密數據,用於後端的接口解析
  • signature加密數據

接口返回的數據如下

<span style="color:#444444">{
    <span style="color:#444444">"errcode"</span>: <span style="color:#880000">200</span>,
    <span style="color:#444444">"msg"</span>: <span style="color:#880000">"SUCCESS"</span>,
    <span style="color:#444444">"data"</span>: {
        <span style="color:#444444">"uid"</span>: <span style="color:#880000">34098</span>,
        <span style="color:#444444">"unionid"</span>: <span style="color:#880000">"xxx"</span>,
    }
}</span>

6.建表

1)用戶表,其中比較重要的字段是union_id,因爲我們是有多個小程序和公衆號,因此使用這個來區分唯一的用戶編號

<span style="color:#444444"><span style="color:#333333"><strong>DROP</strong></span> <span style="color:#333333"><strong>TABLE</strong></span> <span style="color:#333333"><strong>IF</strong></span> <span style="color:#333333"><strong>EXISTS</strong></span> <span style="color:#880000">`jz_wxa_user`</span>;
<span style="color:#333333"><strong>CREATE</strong></span> <span style="color:#333333"><strong>TABLE</strong></span> <span style="color:#880000">`jz_wxa_user`</span> (
  <span style="color:#880000">`id`</span> <span style="color:#397300">int</span>(<span style="color:#880000">10</span>) <span style="color:#333333"><strong>unsigned</strong></span> <span style="color:#333333"><strong>NOT</strong></span> <span style="color:#78a960">NULL</span> AUTO_INCREMENT,
  <span style="color:#880000">`uid`</span> <span style="color:#397300">bigint</span>(<span style="color:#880000">18</span>) <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span>,
  <span style="color:#880000">`openid`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">255</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'openid'</span>,
  <span style="color:#880000">`user_name`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">100</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8mb4 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#880000">''</span>,
  <span style="color:#880000">`nick_name`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">100</span>) <span style="color:#333333"><strong>COLLATE</strong></span> utf8mb4_unicode_ci <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#880000">''</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'用戶暱稱'</span>,
  <span style="color:#880000">`sex`</span> enum(<span style="color:#880000">'0'</span>,<span style="color:#880000">'1'</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#880000">'1'</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'性別'</span>,
  <span style="color:#880000">`avatar`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">255</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'用戶頭像'</span>,
  <span style="color:#880000">`province`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">100</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'省份'</span>,
  <span style="color:#880000">`city`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">100</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'城市'</span>,
  <span style="color:#880000">`country`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">100</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'國家'</span>,
  <span style="color:#880000">`wx_union_id`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">255</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'公衆平臺的唯一id'</span>,
  <span style="color:#880000">`from_url`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">255</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'來源url'</span>,
  <span style="color:#880000">`created_at`</span> <span style="color:#333333"><strong>timestamp</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span>,
  <span style="color:#880000">`updated_at`</span> <span style="color:#333333"><strong>timestamp</strong></span> <span style="color:#78a960">NULL</span> <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#78a960">NULL</span>,
  <span style="color:#880000">`from_appid`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">30</span>) <span style="color:#333333"><strong>COLLATE</strong></span> utf8mb4_unicode_ci <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#880000">'wx95fc895bebd3743b'</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'來源appid'</span>,
  <span style="color:#880000">`wx_header`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">150</span>) <span style="color:#333333"><strong>COLLATE</strong></span> utf8mb4_unicode_ci <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#880000">''</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'微信頭像'</span>,
  <span style="color:#880000">`gh_openid`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">60</span>) <span style="color:#333333"><strong>COLLATE</strong></span> utf8mb4_unicode_ci <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#880000">''</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'微信公衆號openid'</span>,
  <span style="color:#880000">`phone`</span> <span style="color:#397300">varchar</span>(<span style="color:#880000">30</span>) <span style="color:#397300">CHARACTER</span> <span style="color:#333333"><strong>SET</strong></span> utf8 <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#880000">''</span> <span style="color:#333333"><strong>COMMENT</strong></span> <span style="color:#880000">'手機號碼'</span>,
  PRIMARY <span style="color:#333333"><strong>KEY</strong></span> (<span style="color:#880000">`id`</span>),
  <span style="color:#333333"><strong>KEY</strong></span> <span style="color:#880000">`idx_uid_union_id`</span> (<span style="color:#880000">`uid`</span>,<span style="color:#880000">`wx_union_id`</span>)
) <span style="color:#333333"><strong>ENGINE</strong></span>=<span style="color:#333333"><strong>InnoDB</strong></span> AUTO_INCREMENT=<span style="color:#880000">1</span> <span style="color:#333333"><strong>DEFAULT</strong></span> <span style="color:#333333"><strong>CHARSET</strong></span>=utf8mb4 <span style="color:#333333"><strong>COLLATE</strong></span>=utf8mb4_unicode_ci;</span>

實現步驟

用戶授權時序圖

關鍵代碼

小程序端

小程序端的獲取用戶信息流程

1)調用login方法獲取code

2)調用getUserInfo方法獲取用戶的加密數據

3)調用後端的用戶授權接口將用戶信息保存到服務端

4)保存後端接口返回的uid和unionid到localstorage中,作爲全局參數

獲取用戶的授權信息

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

服務端

入口方法

<span style="color:#444444"><span style="color:#888888">/**
     * api接口開發
     * 獲取詳情的接口
     * <span style="color:#333333"><strong>@param</strong></span> $uid 用戶編號
     * <span style="color:#333333"><strong>@param</strong></span> $iv 向量
     * <span style="color:#333333"><strong>@param</strong></span> $encryptedData 微信加密的數據
     * <span style="color:#333333"><strong>@param</strong></span> $rawData 判斷是否爲今天
     * <span style="color:#333333"><strong>@param</strong></span> $signature 簽名
     * <span style="color:#333333"><strong>@return</strong></span> array
     */</span>
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>static</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>authorization</strong></span>($appid,$appsecret,$code,$iv,$encryptedData,$rawData,$signature){
        $result = <span style="color:#333333"><strong>self</strong></span>::decodeWxData($appid,$appsecret,$code,$iv,$encryptedData);
        <span style="color:#333333"><strong>if</strong></span>($result[<span style="color:#880000">'errcode'</span>] != <span style="color:#880000">200</span>){
            <span style="color:#333333"><strong>return</strong></span> $result;
        }
        <span style="color:#888888">//處理微信授權的邏輯</span>
        $wxUserData = $result[<span style="color:#880000">'data'</span>];
        error_log(<span style="color:#880000">"authorization data=============>"</span>);
        error_log(json_encode($wxUserData));
        $uid = WxaUserService::regWxaUser($wxUserData);
        $data[<span style="color:#880000">'uid'</span>] = $uid[<span style="color:#880000">'uid'</span>];
        $data[<span style="color:#880000">'unionid'</span>] =  $uid[<span style="color:#880000">'unionid'</span>];
        $result[<span style="color:#880000">'data'</span>] = $data;
        <span style="color:#333333"><strong>return</strong></span> $result;
    }
    
    <span style="color:#888888">/**
     * 解密微信的數據
     * <span style="color:#333333"><strong>@param</strong></span> $code wx.login接口返回的code
     * <span style="color:#333333"><strong>@param</strong></span> $iv wx.getUserInfo接口或者wx.getWeRunData返回的iv
     * <span style="color:#333333"><strong>@param</strong></span> $encryptedData wx.getUserInfo接口或者wx.getWeRunData返回的加密數據
     * <span style="color:#333333"><strong>@return</strong></span> array
     */</span>
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>static</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>decodeWxData</strong></span>($appid,$appsecret,$code,$iv,$encryptedData){
        $sessionKeyUrl = sprintf(<span style="color:#880000">'%s?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code'</span>,config(<span style="color:#880000">'param.wxa_user_info_session_key_url'</span>),$appid,$appsecret,$code);
        $rtnJson = curlRequest($sessionKeyUrl);
        $data = json_decode($rtnJson,<span style="color:#333333"><strong>true</strong></span>);
        error_log(<span style="color:#880000">'authorization wx return data========>'</span>);
        error_log($rtnJson);
        <span style="color:#333333"><strong>if</strong></span>(<span style="color:#333333"><strong>isset</strong></span>($data[<span style="color:#880000">'errcode'</span>])){
            <span style="color:#333333"><strong>return</strong></span> $data;
        }
        $sessionKey = $data[<span style="color:#880000">'session_key'</span>];
        $wxHelper = <span style="color:#333333"><strong>new</strong></span> WxBizDataHelper($appid,$sessionKey,$encryptedData,$iv);
        $data[<span style="color:#880000">'errcode'</span>] = <span style="color:#880000">200</span>;
        $data[<span style="color:#880000">'data'</span>] = [];
        <span style="color:#333333"><strong>if</strong></span>(!$wxData = $wxHelper->getData()){
            $data[<span style="color:#880000">'errcode'</span>] = <span style="color:#880000">-1</span>;
        }<span style="color:#333333"><strong>else</strong></span>{
            error_log(<span style="color:#880000">'current wx return data is =========>'</span>.json_encode($wxData));
            $data[<span style="color:#880000">'data'</span>] = $wxData;
        }
        <span style="color:#333333"><strong>return</strong></span> $data;
    }</span>

保存用戶信息的方法

<span style="color:#444444"><span style="color:#888888">/**
     * 保存用戶信息的方法
     * <span style="color:#333333"><strong>@param</strong></span> $wxaUserData
     * <span style="color:#333333"><strong>@param</strong></span> $regFromGh 表示是否從公衆號進行註冊
     */</span>
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>regWxaUser</strong></span>($wxaUserData,$regFromGh = false)
    {
        $value = $wxaUserData[<span style="color:#880000">'unionId'</span>];
        $key = getCacheKey(<span style="color:#880000">'redis_key.cache_key.zset_list.lock'</span>) . $value;
        $newExpire = RedisHelper::getLock($key);
        $data =  <span style="color:#333333"><strong>$this</strong></span>->storeWxaUser($wxaUserData,$regFromGh);
        RedisHelper::releaseLock($key, $newExpire);
        <span style="color:#333333"><strong>return</strong></span> $data;
    }
    
    <span style="color:#888888">/**
     * 保存信息
     * <span style="color:#333333"><strong>@param</strong></span> $wxaUserData
     * <span style="color:#333333"><strong>@return</strong></span> mixed
     */</span>
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>storeWxaUser</strong></span>($wxaUserData,$regFromGh = false)
    {
        $wxUnionId = $wxaUserData[<span style="color:#880000">'unionId'</span>];
        <span style="color:#333333"><strong>if</strong></span> (!$user = <span style="color:#333333"><strong>$this</strong></span>->getByWxUnionId($wxUnionId)) {
            $getAccountDataStartTime = time();
            <span style="color:#888888">//這裏是因爲需要統一賬戶獲取uid,所以這個是用戶中心的接口,如果沒有這個流程,則直接使用數據</span>
            <span style="color:#333333"><strong>if</strong></span>($accountData = AccountCenterHelper::regWxaUser($wxaUserData)){
                $getAccountDataEndTime = time();
                $accountRegTime = $getAccountDataEndTime - $getAccountDataStartTime;
                error_log(<span style="color:#880000">"reg user spend time is ===================>"</span> . $accountRegTime);
                $user = [
                    <span style="color:#880000">'uid'</span> => $accountData[<span style="color:#880000">'uid'</span>],
                    <span style="color:#880000">'user_name'</span> => $accountData[<span style="color:#880000">'user_name'</span>],
                    <span style="color:#880000">'nick_name'</span> => $wxaUserData[<span style="color:#880000">'nickName'</span>],
                    <span style="color:#880000">'sex'</span> => $accountData[<span style="color:#880000">'sex'</span>],
                    <span style="color:#880000">'wx_union_id'</span> => $accountData[<span style="color:#880000">'wx_union_id'</span>],
                    <span style="color:#880000">'avatar'</span> => <span style="color:#333333"><strong>isset</strong></span>($accountData[<span style="color:#880000">'avatar'</span>])?$accountData[<span style="color:#880000">'avatar'</span>]:<span style="color:#880000">""</span>,
                    <span style="color:#880000">'from_appid'</span> => $accountData[<span style="color:#880000">'from_appid'</span>],
                    <span style="color:#880000">'province'</span> => $wxaUserData[<span style="color:#880000">'province'</span>],
                    <span style="color:#880000">'city'</span> => $wxaUserData[<span style="color:#880000">'city'</span>],
                    <span style="color:#880000">'country'</span> => $wxaUserData[<span style="color:#880000">'country'</span>],
                    <span style="color:#880000">'openid'</span> => $wxaUserData[<span style="color:#880000">'openId'</span>],
                    <span style="color:#880000">'wx_header'</span> => <span style="color:#333333"><strong>isset</strong></span>($wxaUserData[<span style="color:#880000">'avatarUrl'</span>])?$wxaUserData[<span style="color:#880000">'avatarUrl'</span>]:<span style="color:#880000">""</span>,
                    <span style="color:#880000">'gh_openid'</span> => $regFromGh?$wxaUserData[<span style="color:#880000">'openId'</span>]:<span style="color:#880000">""</span>,
                ];
                error_log(<span style="color:#880000">"insert data=============>"</span> . json_encode($user));
                $user = <span style="color:#333333"><strong>$this</strong></span>->store($user);
                $regApiUserEndTime = time();
                error_log(<span style="color:#880000">" reg api user spend time================>"</span> . ($regApiUserEndTime - $getAccountDataEndTime));
                error_log(<span style="color:#880000">" after insert data=============>"</span> . json_encode($user));
            }
        }<span style="color:#333333"><strong>else</strong></span>{
            <span style="color:#333333"><strong>if</strong></span>(!$user[<span style="color:#880000">'wx_header'</span>]){
                $updateData = [
                    <span style="color:#880000">'id'</span> => $user[<span style="color:#880000">'id'</span>],
                    <span style="color:#880000">'uid'</span> => $user[<span style="color:#880000">'uid'</span>],
                    <span style="color:#880000">'wx_header'</span> => $wxaUserData[<span style="color:#880000">'avatarUrl'</span>],
                ];
                <span style="color:#333333"><strong>$this</strong></span>->update($updateData);
            }
            <span style="color:#888888">//同步用戶的openid</span>
            <span style="color:#333333"><strong>if</strong></span>($wxaUserData[<span style="color:#880000">'openId'</span>] != $user[<span style="color:#880000">'openid'</span>]){
                $updateData = [
                    <span style="color:#880000">'id'</span> => $user[<span style="color:#880000">'id'</span>],
                    <span style="color:#880000">'uid'</span> => $user[<span style="color:#880000">'uid'</span>],
                    <span style="color:#880000">'openid'</span> => $wxaUserData[<span style="color:#880000">'openId'</span>],
                ];
                <span style="color:#333333"><strong>$this</strong></span>->update($updateData);
            }
        }
        $data[<span style="color:#880000">'uid'</span>] = $user[<span style="color:#880000">'uid'</span>];
        $data[<span style="color:#880000">'unionid'</span>] = $wxUnionId;
        <span style="color:#333333"><strong>return</strong></span> $data;
    }</span>

根據unionid獲取用戶信息

<span style="color:#444444"><span style="color:#888888">/**
     * 根據unionid獲取用戶信息
     */</span>
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>getByWxUnionId</strong></span>($unionId)
    {
        $cacheKey = getCacheKey(<span style="color:#880000">'redis_key.cache_key.wxa_user.info'</span>) . $unionId;
        $value = <span style="color:#333333"><strong>$this</strong></span>->remember($cacheKey, <span style="color:#333333"><strong>function</strong></span> () <span style="color:#880000"><strong>use</strong></span> ($unionId) {
            $userInfo = WxaUser::where(<span style="color:#880000">'wx_union_id'</span>, $unionId)->first();
            $userInfo = <span style="color:#333333"><strong>$this</strong></span>->compactUserInfo($userInfo);
            <span style="color:#333333"><strong>return</strong></span> $userInfo;
        });
        <span style="color:#333333"><strong>return</strong></span> $value;
    }</span>

WxBizDataHelper工具類

<span style="color:#444444"><span style="color:#1f7199"><?php</span>
<span style="color:#888888">/**
 * Created by PhpStorm.
 * User: Auser
 * Time: 11:17
 */</span>

<span style="color:#333333"><strong>namespace</strong></span> <span style="color:#880000"><strong>App</strong></span>\<span style="color:#880000"><strong>Http</strong></span>\<span style="color:#880000"><strong>Base</strong></span>\<span style="color:#880000"><strong>Wx</strong></span>;


<span style="color:#333333"><strong>class</strong></span> <span style="color:#880000"><strong>WxBizDataHelper</strong></span>
{

    <span style="color:#333333"><strong>private</strong></span> $appid;
    <span style="color:#333333"><strong>private</strong></span> $seesionKey ;
    <span style="color:#333333"><strong>private</strong></span> $encryptedData;
    <span style="color:#333333"><strong>private</strong></span> $iv;
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>__construct</strong></span>($appid, $sessionKey,$encryptedData, $iv)
    {
        <span style="color:#333333"><strong>$this</strong></span>->appid = $appid;
        <span style="color:#333333"><strong>$this</strong></span>->seesionKey = $sessionKey;
        <span style="color:#333333"><strong>$this</strong></span>->encryptedData = $encryptedData;
        <span style="color:#333333"><strong>$this</strong></span>->iv = $iv;
    }

    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>getData</strong></span>(){
        $pc = <span style="color:#333333"><strong>new</strong></span> WXBizDataCrypt(<span style="color:#333333"><strong>$this</strong></span>->appid, <span style="color:#333333"><strong>$this</strong></span>->seesionKey);
        $json = <span style="color:#880000">''</span>;
        $errCode = $pc->decryptData(<span style="color:#333333"><strong>$this</strong></span>->encryptedData, <span style="color:#333333"><strong>$this</strong></span>->iv, $json);
        $data = [];
        <span style="color:#333333"><strong>if</strong></span> ($errCode == <span style="color:#880000">0</span>) {
            $data = json_decode($json,<span style="color:#333333"><strong>true</strong></span>);
        }
        <span style="color:#333333"><strong>return</strong></span> $data;
    }


}</span>

WXBizDataCrypt工具類

<span style="color:#444444"><span style="color:#1f7199"><?php</span>
<span style="color:#888888">/**
 * Created by PhpStorm.
 * User: Auser
 * Time: 10:38
 */</span>

<span style="color:#333333"><strong>namespace</strong></span> <span style="color:#880000"><strong>App</strong></span>\<span style="color:#880000"><strong>Http</strong></span>\<span style="color:#880000"><strong>Base</strong></span>\<span style="color:#880000"><strong>Wx</strong></span>;

<span style="color:#333333"><strong>use</strong></span> <span style="color:#880000"><strong>App</strong></span>\<span style="color:#880000"><strong>Http</strong></span>\<span style="color:#880000"><strong>Base</strong></span>\<span style="color:#880000"><strong>Wx</strong></span>\<span style="color:#880000"><strong>Prpcrypt</strong></span>;
<span style="color:#333333"><strong>use</strong></span> <span style="color:#880000"><strong>App</strong></span>\<span style="color:#880000"><strong>Http</strong></span>\<span style="color:#880000"><strong>Base</strong></span>\<span style="color:#880000"><strong>Wx</strong></span>\<span style="color:#880000"><strong>ErrorCode</strong></span>;
<span style="color:#333333"><strong>use</strong></span> <span style="color:#880000"><strong>App</strong></span>\<span style="color:#880000"><strong>Http</strong></span>\<span style="color:#880000"><strong>Base</strong></span>\<span style="color:#880000"><strong>Wx</strong></span>\<span style="color:#880000"><strong>PKCS7Encoder</strong></span>;
<span style="color:#333333"><strong>class</strong></span> <span style="color:#880000"><strong>WXBizDataCrypt</strong></span>
{

    <span style="color:#333333"><strong>private</strong></span> $appid;
    <span style="color:#333333"><strong>private</strong></span> $sessionKey;

    <span style="color:#888888">/**
     * 構造函數
     * <span style="color:#333333"><strong>@param</strong></span> $sessionKey string 用戶在小程序登錄後獲取的會話密鑰
     * <span style="color:#333333"><strong>@param</strong></span> $appid string 小程序的appid
     */</span>
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>__construct</strong></span>( $appid, $sessionKey)
    {
        <span style="color:#333333"><strong>$this</strong></span>->sessionKey = $sessionKey;
        <span style="color:#333333"><strong>$this</strong></span>->appid = $appid;
    }


    <span style="color:#888888">/**
     * 檢驗數據的真實性,並且獲取解密後的明文.
     * <span style="color:#333333"><strong>@param</strong></span> $encryptedData string 加密的用戶數據
     * <span style="color:#333333"><strong>@param</strong></span> $iv string 與用戶數據一同返回的初始向量
     * <span style="color:#333333"><strong>@param</strong></span> $data string 解密後的原文
     *
     * <span style="color:#333333"><strong>@return</strong></span> int 成功0,失敗返回對應的錯誤碼
     */</span>
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>decryptData</strong></span>( $encryptedData, $iv, &$data )
    {
        <span style="color:#333333"><strong>if</strong></span> (strlen(<span style="color:#333333"><strong>$this</strong></span>->sessionKey) != <span style="color:#880000">24</span>) {
            <span style="color:#333333"><strong>return</strong></span> ErrorCode::$IllegalAesKey;
        }
        $aesKey=base64_decode(<span style="color:#333333"><strong>$this</strong></span>->sessionKey);


        <span style="color:#333333"><strong>if</strong></span> (strlen($iv) != <span style="color:#880000">24</span>) {
            <span style="color:#333333"><strong>return</strong></span> ErrorCode::$IllegalIv;
        }
        $aesIV=base64_decode($iv);

        $aesCipher=base64_decode($encryptedData);

        $pc = <span style="color:#333333"><strong>new</strong></span> Prpcrypt($aesKey);
        $result = $pc->decrypt($aesCipher,$aesIV);

        <span style="color:#333333"><strong>if</strong></span> ($result[<span style="color:#880000">0</span>] != <span style="color:#880000">0</span>) {
            <span style="color:#333333"><strong>return</strong></span> $result[<span style="color:#880000">0</span>];
        }

        $dataObj=json_decode( $result[<span style="color:#880000">1</span>] );
        <span style="color:#333333"><strong>if</strong></span>( $dataObj  == <span style="color:#333333"><strong>NULL</strong></span> )
        {
            <span style="color:#333333"><strong>return</strong></span> ErrorCode::$IllegalBuffer;
        }
        <span style="color:#333333"><strong>if</strong></span>( $dataObj->watermark->appid != <span style="color:#333333"><strong>$this</strong></span>->appid )
        {
            <span style="color:#333333"><strong>return</strong></span> ErrorCode::$IllegalBuffer;
        }
        $data = $result[<span style="color:#880000">1</span>];
        <span style="color:#333333"><strong>return</strong></span> ErrorCode::$OK;
    }

}</span>

Prpcrypt工具類

<span style="color:#444444"><span style="color:#1f7199"><?php</span>
<span style="color:#888888">/**
 * Created by PhpStorm.
 * User: Auser
 * Time: 10:55
 */</span>

<span style="color:#333333"><strong>namespace</strong></span> <span style="color:#880000"><strong>App</strong></span>\<span style="color:#880000"><strong>Http</strong></span>\<span style="color:#880000"><strong>Base</strong></span>\<span style="color:#880000"><strong>Wx</strong></span>;

<span style="color:#333333"><strong>class</strong></span> <span style="color:#880000"><strong>Prpcrypt</strong></span>
{
    <span style="color:#333333"><strong>public</strong></span> $key;

    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>__construct</strong></span>($key)
    {
        <span style="color:#333333"><strong>$this</strong></span>->key = $key;
    }

    <span style="color:#888888">/**
     * 對密文進行解密
     * <span style="color:#333333"><strong>@param</strong></span> string $aesCipher 需要解密的密文
     * <span style="color:#333333"><strong>@param</strong></span> string $aesIV 解密的初始向量
     * <span style="color:#333333"><strong>@return</strong></span> string 解密得到的明文
     */</span>
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>function</strong></span> <span style="color:#880000"><strong>decrypt</strong></span>($aesCipher, $aesIV)
    {

        <span style="color:#333333"><strong>try</strong></span> {
            $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, <span style="color:#880000">''</span>, MCRYPT_MODE_CBC, <span style="color:#880000">''</span>);
            mcrypt_generic_init($module, <span style="color:#333333"><strong>$this</strong></span>->key, $aesIV);
            <span style="color:#888888">//解密</span>
            $decrypted = mdecrypt_generic($module, $aesCipher);
            mcrypt_generic_deinit($module);
            mcrypt_module_close($module);
        } <span style="color:#333333"><strong>catch</strong></span> (<span style="color:#333333"><strong>Exception</strong></span> $e) {
            <span style="color:#333333"><strong>return</strong></span> <span style="color:#333333"><strong>array</strong></span>(ErrorCode::$IllegalBuffer, <span style="color:#333333"><strong>null</strong></span>);
        }


        <span style="color:#333333"><strong>try</strong></span> {
            $result = PKCS7Encoder2::decode($decrypted);
        } <span style="color:#333333"><strong>catch</strong></span> (<span style="color:#333333"><strong>Exception</strong></span> $e) {
            <span style="color:#888888">//print $e;</span>
            <span style="color:#333333"><strong>return</strong></span> <span style="color:#333333"><strong>array</strong></span>(ErrorCode::$IllegalBuffer, <span style="color:#333333"><strong>null</strong></span>);
        }
        <span style="color:#333333"><strong>return</strong></span> <span style="color:#333333"><strong>array</strong></span>(<span style="color:#880000">0</span>, $result);
    }
}</span>

ErrorCode狀態代碼類

<span style="color:#444444"><span style="color:#1f7199"><?php</span>
<span style="color:#888888">/**
 * Created by PhpStorm.
 * User: Auser
 * Time: 10:33
 */</span>

<span style="color:#333333"><strong>namespace</strong></span> <span style="color:#880000"><strong>App</strong></span>\<span style="color:#880000"><strong>Http</strong></span>\<span style="color:#880000"><strong>Base</strong></span>\<span style="color:#880000"><strong>Wx</strong></span>;


<span style="color:#333333"><strong>class</strong></span> <span style="color:#880000"><strong>ErrorCode</strong></span>
{
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>static</strong></span> $OK = <span style="color:#880000">0</span>;
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>static</strong></span> $IllegalAesKey = <span style="color:#880000">-41001</span>;
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>static</strong></span> $IllegalIv = <span style="color:#880000">-41002</span>;
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>static</strong></span> $IllegalBuffer = <span style="color:#880000">-41003</span>;
    <span style="color:#333333"><strong>public</strong></span> <span style="color:#333333"><strong>static</strong></span> $DecodeBase64Error = <span style="color:#880000">-41004</span>;

}</span>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章