概述
記錄一個企業微信jssdk的使用,因為要用到圖片上傳、掃描二維碼等工具。項目是uniapp開發的h5項目,fastadmin(thinkphp5)后端
先看官方文檔
https://developer.work.weixin.qq.com/document/path/90547#%E5%BA%94%E7%94%A8%E8%BA%AB%E4%BB%BD%E6%B3%A8%E5%86%8Chttps://developer.work.weixin.qq.com/document/path/90547#%E5%BA%94%E7%94%A8%E8%BA%AB%E4%BB%BD%E6%B3%A8%E5%86%8C
一、安裝sdk
安裝及使用按照官方文檔的操作,安裝完之后重啟一下編輯器!?
二、接口鑒權
接口鑒權有兩種方式,一種是企業身份注冊,一種是應用身份注冊。
這里我選擇了應用注冊。
涉及到js-sdk簽名算法,見下面的官方文檔:
https://developer.work.weixin.qq.com/document/path/90506
如果已經實現了可以繼續往下。這里展開說說怎么做(前端的童鞋可以先回避,這里依靠后端實現)。
對應的后端代碼,但是我這里實測是簽名無效的,不知道問題出現在哪里,最后選擇 把ticket返回給前端,用官方的簽名算法去計算簽名。
/*** 企業微信JS-SDK配置接口*/public function wwregister(){$url = $this->request->post('url');if (!$url) {$this->error('缺少URL參數');}try {// 1. 獲取access_token$accessToken = $this->getAccessToken();// 2. 獲取企業級jsapi_ticket$jsapiTicket = $this->getJsapiTicket($accessToken);// 3. 獲取應用級jsapi_ticket$appJsapiTicket = $this->getAppJsapiTicket($this->app_id, $this->app_secret);// 4. 生成企業簽名和應用簽名$configSignature = $this->generateConfigSignature($jsapiTicket, $url);$agentConfigSignature = $this->generateAgentConfigSignature($appJsapiTicket, $url);// 5. 構建響應數據$config = ['corpId' => $this->corpid,'agentId' => $this->app_id,'jsApiList' => ['chooseImage', 'scanQRCode'],'configSignature' => $configSignature,'agentConfigSignature' => $agentConfigSignature,'timestamp' => $configSignature['timestamp'],'nonceStr' => $configSignature['nonceStr'],'tk1'=>$jsapiTicket,'tk2'=>$appJsapiTicket];$this->success('獲取成功', $config);} catch (Exception $e) {$this->error('獲取失敗: ' . $e->getMessage());}}/*** 生成企業級簽名*/private function generateConfigSignature($jsapiTicket, $url){$timestamp = time();$nonceStr = $this->createNonceStr();// 拼接簽名參數$string = "jsapi_ticket={$jsapiTicket}&noncestr={$nonceStr}×tamp={$timestamp}&url={$url}";// 計算SHA1簽名$signature = sha1($string);return ['timestamp' => $timestamp,'nonceStr' => $nonceStr,'signature' => $signature];}/*** 生成應用級簽名*/private function generateAgentConfigSignature($appJsapiTicket, $url){$timestamp = time();$nonceStr = $this->createNonceStr();// 拼接簽名參數$string = "jsapi_ticket={$appJsapiTicket}&noncestr={$nonceStr}×tamp={$timestamp}&url={$url}";// 計算SHA1簽名$signature = sha1($string);return ['timestamp' => $timestamp,'nonceStr' => $nonceStr,'signature' => $signature];}/*** 獲取應用jsapi_ticket*/private function getAppJsapiTicket($agentid,$appsecret){// 從緩存獲取或重新請求$jsapiTicket = Cache::get($agentid.'wecom_appjsapi_ticket');if (!$jsapiTicket) {// 這里應該拿應用的accesstoken$accessToken = getAppAccessToken($agentid,$appsecret);// 跟獲取企業jsapi_ticket的卻別在與請求的url不一樣$url = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token={$accessToken}&type=agent_config";$result = $this->httpGet($url);$result = json_decode($result, true);if (isset($result['ticket'])) {$jsapiTicket = $result['ticket'];Cache::set($agentid.'wecom_appjsapi_ticket', $jsapiTicket, 7100); // 提前100秒過期} else {throw new Exception('獲取jsapi_ticket失敗: ' . json_encode($result));}}return $jsapiTicket;}// 獲取應用的accesstokenpublic function getAppAccessToken($agentid,$appsecret){$token = Cache::get($agentid.'_wecom_access_token');if (!$token) {$config = get_addon_config('wecom');$corpid = $this->corpid;$corpsecret = $appsecret;$url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpid}&corpsecret={$corpsecret}";$result = $this->httpGet($url);$result = json_decode($result, true);if (isset($result['access_token'])) {$accessToken = $result['access_token'];Cache::set($agentid.'_wecom_access_token', $accessToken, 7100); // 提前100秒過期} else {throw new Exception('獲取access_token失敗: ' . json_encode($result));}}return $token;}/*** 獲取access_token*/private function getAccessToken(){// 從緩存獲取或重新請求$accessToken = Cache::get('wecom_access_token');if (!$accessToken) {$corpid = $this->corpid;$corpsecret = $this->corpsecret;$url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpid}&corpsecret={$corpsecret}";$result = $this->httpGet($url);$result = json_decode($result, true);if (isset($result['access_token'])) {$accessToken = $result['access_token'];Cache::set('wecom_access_token', $accessToken, 7100); // 提前100秒過期} else {throw new Exception('獲取access_token失敗: ' . json_encode($result));}}return $accessToken;}
回到前端,在頁面中寫方法
三、遇到的問題
1、項目調試使用微信開發者工具;
2、項目本地開發,會報錯“invalid url domain”
打包線上之后正常,是否只能一邊改一邊打包上線測試呢~我也沒搞清楚是否有解決辦法,不然不大方便啊!!
項目上線后,可以成功拿到jssdk權限?
3、invalid signature
上面已經提到過了,如果拿后端返回的簽名是無效的(當然不排除我寫的后端方法有問題~)
雖然官方文檔給出排錯的文檔,但是對接的心好累,下回分解了~
四、接口的使用:選擇圖像
經過大費周章的前期準備,萬事俱備,終于可以正常使用工具了,例如圖像選擇
// 選擇圖片const chooseImage = () => {if (images.value.length >= 5) {uni.showToast({title: '最多上傳5張圖片',icon: 'none'});return;}ww.chooseImage({count: 5 - images.value.length, // 最多可以選擇的圖片張數sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有success: (res : any) => {// 返回選定照片的本地ID列表,localId可以作為img標簽的src屬性顯示圖片const localIds = res.localIds;// 上傳圖片到微信服務器并獲取服務器IDlocalIds.forEach((localId : string) => {uploadImageToWechat(localId);});},fail: (err : any) => {console.error('選擇圖片失敗', err);uni.showToast({title: '選擇圖片失敗',icon: 'none'});}});};
?
看到這個窗口,前期準備功夫全不費工夫,終于可以上傳文件了。
但是這僅僅是開始~圖片會上傳到企微服務器,還得拉下來保存到自己的服務器。又可以另外寫一篇文章敘述了。