欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解nodejs 開(kāi)發(fā)企業(yè)微信第三方應(yīng)用入門(mén)教程

 更新時(shí)間:2019年03月12日 14:32:16   作者:Worktile  
這篇文章主要介紹了詳解nodejs 開(kāi)發(fā)企業(yè)微信第三方應(yīng)用入門(mén)教程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

最近公司要開(kāi)發(fā)企業(yè)微信端的 Worktile,以前做的是企業(yè)微信內(nèi)部應(yīng)用,所以只適用于私有部署客戶(hù),而對(duì)于公有云客戶(hù)就無(wú)法使用,所有就準(zhǔn)備開(kāi)發(fā)企業(yè)微信的第三方應(yīng)用,本文主要介紹在調(diào)研階段遇到的山珍海味。

開(kāi)發(fā)之前你需要前注冊(cè)為第三方服務(wù)商,然后用第三方服務(wù)商的賬號(hào)創(chuàng)建應(yīng)用,創(chuàng)建之后只需要管理員授權(quán)應(yīng)用,第三方服務(wù)商即可為用戶(hù)提供服務(wù)。

一、注冊(cè)第三發(fā)服務(wù)商

登陸 服務(wù)商官網(wǎng) ,注冊(cè)成為服務(wù)商,并登陸服務(wù)商管理后臺(tái)。

二、配置開(kāi)發(fā)信息

在創(chuàng)建應(yīng)用之前,首先要配置好通用開(kāi)發(fā)參數(shù)

在填寫(xiě)系統(tǒng)事件接收 url 時(shí),要正確響應(yīng)企業(yè)微信驗(yàn)證 url 的請(qǐng)求。這個(gè)可以參考企業(yè)微信后臺(tái),自建應(yīng)用的接收消息的 api 設(shè)置。

在企業(yè)的管理端后臺(tái),進(jìn)入需要設(shè)置接收消息的目標(biāo)應(yīng)用,點(diǎn)擊“接收消息”的“設(shè)置API接收”按鈕,進(jìn)入配置頁(yè)面。

要求填寫(xiě)應(yīng)用的 URL、Token、EncodingAESKey 三個(gè)參數(shù)

  • URL 是企業(yè)后臺(tái)接收企業(yè)微信推送請(qǐng)求的訪問(wèn)協(xié)議和地址,支持 http 或 https 協(xié)議(為了提高安全性,建議使用 https)。
  • Token 可由企業(yè)任意填寫(xiě),用于生成簽名。
  • EncodingAESKey 用于消息體的加密,是 AES 密鑰的 Base64 編碼。

 2.1 驗(yàn)證 url 有效性

當(dāng)點(diǎn)擊保存的時(shí)候,企業(yè)微信會(huì)發(fā)生一條 get 請(qǐng)求到填寫(xiě)的 url

比如 url 設(shè)置的是 https://api.worktile.com , 企業(yè)微信將發(fā)送如下驗(yàn)證請(qǐng)求:

請(qǐng)求地址: https://api.worktile.com/?msg_signature=ASDFQWEXZCVAQFASDFASDFSS×tamp=13500001234&nonce=123412323&echostr=ENCRYPT_STR

參數(shù) 說(shuō)明
msg_signature 企業(yè)微信加密簽名,msg_signature 結(jié)合了企業(yè)填寫(xiě)的 token、請(qǐng)求中的 timestamp、nonce 參數(shù)、加密的消息體
timestamp 時(shí)間戳
nonce 隨機(jī)數(shù)
echostr 加密的字符串。需要解密得到消息內(nèi)容明文,解密后有random、msg_len、msg、receiveid 四個(gè)字段,其中 msg 即為消息內(nèi)容明文

2.1.1 通過(guò)參數(shù) msg_signature 對(duì)請(qǐng)求進(jìn)行校驗(yàn)

首先要把剛才配置時(shí)隨機(jī)生成的 token, timestamp, nonce, msg_encrypt 進(jìn)行 sha1 加密,這里我們可以直接使用 npm 模塊 sha1 進(jìn)行加密,然后判斷得到的 str 是否和 msg_signature 相等。

function sha1(str) {
 const md5sum = crypto.createHash('sha1');
 md5sum.update(str);
 const ciphertext = md5sum.digest('hex');
 return ciphertext;
}
function checkSignature(req, res, encrypt) {
 const query = req.query;
 console.log('Request URL: ', req.url);
 const signature = query.msg_signature;
 const timestamp = query.timestamp;
 const nonce = query.nonce;
 let echostr;
 console.log('encrypt', encrypt);
 if (!encrypt) {
  echostr = query.echostr;
 } else {
  echostr = encrypt;
 }
 console.log('timestamp: ', timestamp);
 console.log('nonce: ', nonce);
 console.log('signature: ', signature);
 // 將 token/timestamp/nonce 三個(gè)參數(shù)進(jìn)行字典序排序
 const tmpArr = [token, timestamp, nonce, echostr];
 const tmpStr = sha1(tmpArr.sort().join(''));
 console.log('Sha1 String: ', tmpStr);
 // 驗(yàn)證排序并加密后的字符串與 signature 是否相等
 if (tmpStr === signature) {
  // 原樣返回echostr參數(shù)內(nèi)容
  const result = _decode(echostr);
  console.log('last', result);
  console.log('Check Success');
  return result;
 } else {
  console.log('Check Failed');
  return 'failed';
 }
}

2.1.2 解密 echostr 得到 msg 并返回

密文解密過(guò)程:

對(duì)剛才生成的 AESKey 進(jìn)行 base64 解碼

const EncodingAESKey = '21IpFqj8qolJbaqPqe1rVTAK5sgkaQ3GQmUKiUQLwRe';
let aesKey = Buffer.from(EncodingAESKey + '=', 'base64');

對(duì) AESKey 進(jìn)行 aes-256-cbc 解密

function _decode(data) {
 let aesKey = Buffer.from('21IpFqj8qolJbaqPqe1rVTAK5sgkaQ3GQmUKiUQLwRe' + '=', 'base64');
 let aesCipher = crypto.createDecipheriv("aes-256-cbc", aesKey, aesKey.slice(0, 16));
 aesCipher.setAutoPadding(false);
 let decipheredBuff = Buffer.concat([aesCipher.update(data, 'base64'), aesCipher.final()]);
 decipheredBuff = PKCS7Decoder(decipheredBuff);
 let len_netOrder_corpid = decipheredBuff.slice(16);
 let msg_len = len_netOrder_corpid.slice(0, 4).readUInt32BE(0);
 const result = len_netOrder_corpid.slice(4, msg_len + 4).toString();
 return result; // 返回一個(gè)解密后的明文-
}
function PKCS7Decoder (buff) {
 var pad = buff[buff.length - 1];
 if (pad < 1 || pad > 32) {
  pad = 0;
 }
 return buff.slice(0, buff.length - pad);
}

然后返回 result 即可

res.end(result);

2.2 回調(diào) url 驗(yàn)證失敗問(wèn)題

驗(yàn)證 URL 時(shí),經(jīng)常會(huì)碰到 URL 驗(yàn)證失敗的問(wèn)題,解決思路是借助微信企業(yè)號(hào) 接口調(diào)試工具

三、創(chuàng)建應(yīng)用

四、測(cè)試應(yīng)用

應(yīng)用創(chuàng)建成功后,服務(wù)商可以授權(quán) 10 個(gè)測(cè)試企業(yè)

從企業(yè)微信應(yīng)用市場(chǎng)發(fā)起授權(quán)時(shí),企業(yè)微信給剛才應(yīng)用設(shè)置的 指令回調(diào) url 發(fā)送一個(gè) post 請(qǐng)求,比如:

https://api.worktile.com/worktile?msg_signature=b99605616153ffbfbe6ebbb500bd211e67ed714d&timestamp=1551076894&nonce=1551709703 ,直接返回成功即可。

各個(gè)事件的回調(diào),服務(wù)商在收到推送后都必須直接返回字符串 “success”,若返回值不是 “success”,企業(yè)微信會(huì)把返回內(nèi)容當(dāng)作錯(cuò)誤信息。

app.post('/worktile', function (req, res) {
 console.log('req.body', req.body);
 res.send('success');
});

測(cè)試應(yīng)用注意事項(xiàng)

  1. 用于安裝測(cè)試的企業(yè)微信帳號(hào)需服務(wù)商自行注冊(cè),每個(gè)應(yīng)用支持同時(shí)添加 10 個(gè)測(cè)試企業(yè)微信賬號(hào)
  2. 安裝測(cè)試的企業(yè)微信帳號(hào)使用的是當(dāng)前的應(yīng)用配置信息,后續(xù)的修改不會(huì)進(jìn)行同步;如需更新應(yīng)用信息請(qǐng)重新授權(quán)安裝
  3. 同一企業(yè)微信帳號(hào),不支持同時(shí)安裝測(cè)試應(yīng)用和正式發(fā)布的應(yīng)用

五、應(yīng)用上線

已認(rèn)證企業(yè)微信的服務(wù)商,可進(jìn)入應(yīng)用管理—點(diǎn)擊提交上線—勾選應(yīng)用—提交上線。

六、用戶(hù)網(wǎng)頁(yè)授權(quán)登錄

6.1 構(gòu)造第三方應(yīng)用網(wǎng)頁(yè)授權(quán)鏈接

如果第三方應(yīng)用需要在打開(kāi)的網(wǎng)頁(yè)里面攜帶用戶(hù)的身份信息,第一步需要構(gòu)造如下的鏈接來(lái)獲取 code:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

參數(shù) 必須 說(shuō)明
appid 第三方應(yīng)用 id(即 ww 或 wx 開(kāi)頭的 suite_id)。注意與企業(yè)的網(wǎng)頁(yè)授權(quán)登錄不同
redirect_uri 授權(quán)后重定向的回調(diào)鏈接地址,請(qǐng)使用 urlencode 對(duì)鏈接進(jìn)行處理 ,注意域名需要設(shè)置為第三方應(yīng)用的可信域名
response_type 返回類(lèi)型,此時(shí)固定為:code
scope 應(yīng)用授權(quán)作用域。snsapi_base:靜默授權(quán),可獲取成員的基礎(chǔ)信息(UserId與DeviceId);snsapi_userinfo:靜默授權(quán),可獲取成員的詳細(xì)信息,但不包含手機(jī)、郵箱等敏感信息;snsapi_privateinfo:手動(dòng)授權(quán),可獲取成員的詳細(xì)信息,包含手機(jī)、郵箱等敏感信息。
state 重定向后會(huì)帶上 state 參數(shù),企業(yè)可以填寫(xiě) a-zA-Z0-9 的參數(shù)值,長(zhǎng)度不可超過(guò) 128 個(gè)字節(jié)
#wechat_redirect 終端使用此參數(shù)判斷是否需要帶上身份信息

企業(yè)員工點(diǎn)擊后,頁(yè)面將跳轉(zhuǎn)至 redirect_uri?code=CODE&state=STATE,第三方應(yīng)用可根據(jù) code 參數(shù)獲得企業(yè)員工的 corpid 與 userid。code 長(zhǎng)度最大為 512 字節(jié)。

6.2 獲取訪問(wèn)用戶(hù)身份

請(qǐng)求方式:GET(HTTPS)

請(qǐng)求地址: https://qyapi.weixin.qq.com/cgi-bin/service/getuserinfo3rd?access_token=SUITE_ACCESS_TOKEN&code=CODE

參數(shù) 必須 說(shuō)明
access_token 第三方應(yīng)用的 suite_access_token,參見(jiàn)“獲取第三方應(yīng)用憑證”
code 通過(guò)成員授權(quán)獲取到的 code,最大為 512 字節(jié)。每次成員授權(quán)帶上的 code 將不一樣,code 只能使用一次,5 分鐘未被使用自動(dòng)過(guò)期。

 6.2.1 獲取第三方應(yīng)用的 suite_access_token

請(qǐng)求方式:POST(HTTPS)

請(qǐng)求地址: https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token

參數(shù) 是否必須 說(shuō)明
suite_id 以 ww 或 wx 開(kāi)頭應(yīng)用 id(對(duì)應(yīng)于舊的以 tj 開(kāi)頭的套件 id)
suite_secret 應(yīng)用 secret
suite_ticket 企業(yè)微信后臺(tái)推送的 ticket

由于第三方服務(wù)商可能托管了大量的企業(yè),其安全問(wèn)題造成的影響會(huì)更加嚴(yán)重,故 API 中除了合法來(lái)源 IP 校驗(yàn)之外,還額外增加了 suite_ticket 作為安全憑證。

獲取 suite_access_token 時(shí),需要 suite_ticket 參數(shù)。suite_ticket 由企業(yè)微信后臺(tái)定時(shí)推送給“指令回調(diào) URL”,每十分鐘更新一次,見(jiàn)推送 suite_ticket

suite_ticket 實(shí)際有效期為 30 分鐘,可以容錯(cuò)連續(xù)兩次獲取 suite_ticket 失敗的情況,但是請(qǐng)永遠(yuǎn)使用最新接收到的 suite_ticket。

通過(guò)本接口獲取的 suite_access_token 有效期為 2 小時(shí),開(kāi)發(fā)者需要進(jìn)行緩存,不可頻繁獲取。

6.2.2 獲取推送 suite_ticket

企業(yè)微信服務(wù)器會(huì)定時(shí)(每十分鐘)推送 ticket。ticket 會(huì)實(shí)時(shí)變更,并用于后續(xù)接口的調(diào)用。

請(qǐng)求方式:POST(HTTPS)

請(qǐng)求地址: https://api.ninesix.cc/worktile?msg_signature=87276aaf15a13e1eb2ebb6d93732ca668c3ddef8&timestamp=1551850300&nonce=1551051655

在發(fā)生授權(quán)、通訊錄變更、ticket 變化等事件時(shí),企業(yè)微信服務(wù)器會(huì)向應(yīng)用的“指令回調(diào) URL”推送相應(yīng)的事件消息,nodejs 接收到的是 xml,解析后拿到 encrypt 字段,然后使用上面配置通用開(kāi)發(fā)參數(shù)的 url 時(shí)用的解密方式,就可以得到 suite_ticket。

6.3 獲取用戶(hù)敏感信息

請(qǐng)求方式:POST(HTTPS)

請(qǐng)求地址: https://qyapi.weixin.qq.com/cgi-bin/service/getuserdetail3rd?access_token=SUITE_ACCESS_TOKEN

{
  "user_ticket": "USER_TICKET"
}

參數(shù) 必須 說(shuō)明
access_token 第三方應(yīng)用的 suite_access_token,參見(jiàn)“獲取第三方應(yīng)用憑證”
user_ticket 成員票據(jù)

返回結(jié)果:

{
  "errcode": 0,
  "errmsg": "ok",
  "corpid": "wwxxxxxxyyyyy",
  "userid": "lisi",
  "name": "李四",
  "mobile": "15913215421",
  "gender": "1",
  "email": "xxx@xx.com",
  "avatar": "http://shp.qpic.cn/bizmp/xxxxxxxxxxx/0",
  "qr_code": "https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=vcfc13b01dfs78e981c"
}

七、用戶(hù)授權(quán)成功

首頁(yè)

詳情頁(yè)

八、給用戶(hù)發(fā)消息

我們可以給推送文本、圖片、視頻、文件、圖文等類(lèi)型。

請(qǐng)求方式:POST(HTTPS)

請(qǐng)求地址: https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN

推送的時(shí)候需要 access_token 和 應(yīng)用的 agentId,第三方服務(wù)商,可通過(guò)接口 獲取企業(yè)授權(quán)信息 獲取該參數(shù)值,其實(shí)可以直接通過(guò)獲取企業(yè)永久授權(quán)碼 直接取到這兩個(gè)值。

在我們測(cè)試安裝應(yīng)用成功之后,企業(yè)微信會(huì) post 一條請(qǐng)求給指令回調(diào) URL,通過(guò)上面的解密方式,可以解析到 xml 中的 auth_code

然后通過(guò) https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=SUITE_ACCESS_TOKENauth_code 可以獲取到 access_token 和 agentId,返回的 agent 是一個(gè)數(shù)組,但僅舊的多應(yīng)用套件授權(quán)時(shí)會(huì)返回多個(gè)agent,對(duì)新的單應(yīng)用授權(quán),永遠(yuǎn)只返回一個(gè) agent。

再通過(guò) access_token 和 agentId 就可以愉快的給用戶(hù)發(fā)送消息了。

當(dāng)點(diǎn)擊鏈接時(shí),可以跳到指定任務(wù)或者日程等,只不過(guò)返回時(shí)還是在企業(yè)微信的消息模塊,并不能自動(dòng)打開(kāi)第三方應(yīng)用,客服回復(fù)不支持這么做。

九、注意事項(xiàng)

api 可能有時(shí)效性,如有差異,以官方 api 為準(zhǔn)。

完整 demo

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論