摘要:事先準備工作申請一個小程序,申請地址傳送門仔細閱讀小程序的用戶授權登陸官方文檔用戶授權登陸的流程仔細閱讀微信用戶數據解密的相關文檔用戶數據解密說明文檔在小程序后臺配置好相應的后端請求地址,路徑是開發開發設置,如圖小程序如果需要做多個
事先準備工作
1.申請一個小程序,申請地址:傳送門
2.仔細閱讀小程序的用戶授權登陸官方文檔:《用戶授權登陸的流程》
3.仔細閱讀微信用戶數據解密的相關文檔:《用戶數據解密說明文檔》
4.在小程序后臺配置好相應的后端請求地址,路徑是:開發---->開發設置,如圖
5.小程序如果需要做多個小程序的打通,還需要在微信開放平臺綁定到開發者賬號下面, 如果不需要union_id請忽略
6.服務端準備一個用戶授權的接口,假設接口鏈接為http://test.dev.com/user/auth...,此接口接受如下參數
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;實現步驟 用戶授權時序圖 關鍵代碼 小程序端 小程序端的獲取用戶信息流程
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工具類
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工具類
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工具類
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狀態代碼類
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30953.html
摘要:背景最近項目需要上線支付寶小程序,同時需要走用戶的授權流程完成用戶信息的存儲,以前做過微信小程序的開發,本以為實現授權的過程是很簡單的事情,但是再實現的過程中還是遇到了不少的坑,因此記錄一下實現的過程學到的知識支付寶開放接口的調用模式以及實 背景 最近項目需要上線支付寶小程序,同時需要走用戶的授權流程完成用戶信息的存儲,以前做過微信小程序的開發,本以為實現授權的過程是很簡單的事情,但是...
摘要:傳統的網頁編程采用的三劍客來實現,在微信小程序中同樣有三劍客。觀察者模式不難實現,重點是如何在微信小程序中搭配其特有的生命周期來使用。交互事件傳統的事件傳遞類型有冒泡型與捕獲型,微信小程序中自然也有。 本文由作者鄒永勝授權網易云社區發布。 簡介為了更好的展示我們即時通訊SDK強悍的能力,網易云信IM SDK微信小程序DEMO的開發就提上了日程。用產品的話說就是: 云信 IM 小程序 S...
摘要:解析進到首頁其實關鍵字在本地就隨機取完了,在首頁中的方法中就通過緩存了要畫的元素,比如關鍵字這里是圖片關鍵字解析語也是圖片畢竟微信小程序的不支持字體等等。 一、Canvas應用的背景(個人理解)及基礎語法 背景 從2012年開始,微信那個時候用戶的積累的量已經非常大了,推出公眾號,當然大屏智能手機在那個時候也流行,傳統的大眾媒體逐步消亡,像微信公眾號這樣的新媒體盛行。企業的廣告投入開始...
摘要:注沒有在微信開放平臺做開發者資質認證的就不要浪費時間了,沒認證無法獲取,認證費用元年,微信授權登錄流程第一步獲取用戶臨時登錄憑證第二步獲取加密過的數據和解密參數第三步把步驟一二中的傳到開發者自己服務端第三步服務端獲取到之后用方法請求如下微信 注:沒有在微信開放平臺做開發者資質認證的就不要浪費時間了,沒認證無法獲取unionId,認證費用300元/年,emmmm.... 微信授權登錄流程...
閱讀 3280·2023-04-26 02:09
閱讀 2574·2021-11-24 09:39
閱讀 3268·2021-11-16 11:52
閱讀 3614·2021-10-26 09:50
閱讀 2771·2021-10-08 10:05
閱讀 2456·2021-09-22 15:25
閱讀 3299·2019-08-30 13:14
閱讀 908·2019-08-29 17:06