一、獲取access_token
參考文檔:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
1.用途
調(diào)用公眾號的各個接口都需要用到access_token
備注:占用大小至少512個字符空間、有效期目前為2個小時,需要定時刷新,重復(fù)刷新獲取惠導(dǎo)致上一次獲取的access_token失效
2.獲取方式
https請求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
備注:調(diào)用接口時,請登錄“微信公眾平臺-開發(fā)-基本配置”提前將服務(wù)器IP地址添加到IP白名單中,點擊查看設(shè)置方法,否則將無法調(diào)用成功。小程序無需配置IP白名單。
注意獲取到access_token后需要存在數(shù)據(jù)庫中,并且設(shè)置一個時間(2小時過期),最好在過期之前重新獲取一次,更新數(shù)據(jù)庫中的值。
二、接口配置信息(驗證服務(wù)器有效性)
配置服務(wù)器地址需要一個外網(wǎng)地址,開發(fā)過程中可以使用內(nèi)網(wǎng)穿透工具,將一個外網(wǎng)地址指向你的本地服務(wù),方便調(diào)試。
常用的內(nèi)網(wǎng)穿透工具:
mac: ngrok
windows: 花生殼、nat123

url:服務(wù)器接口地址
token:信息需要與服務(wù)器定義的token一直
點擊提交按鈕時,微信會向服務(wù)器發(fā)送一個get請求,請求地址就是配置的url,這個請求會攜帶signature(微信加密簽名,signature結(jié)合了開發(fā)者填寫的token參數(shù)和請求中的timestamp參數(shù)、nonce參數(shù))、timestamp(時間戳)、nonce(隨機數(shù))、echostr(隨機字符串)四個字符串過來
服務(wù)器拿到這些字符串之后進(jìn)行校驗:
1)將token、timestamp、nonce三個參數(shù)進(jìn)行字典序排序
2)將三個參數(shù)字符串拼接成一個字符串進(jìn)行sha1加密
3)開發(fā)者獲得加密后的字符串可與signature對比,標(biāo)識該請求來源于微信
代碼可參考:

三、被動回復(fù)用戶消息
1.接收post請求
當(dāng)用戶向微信公眾號發(fā)送消息的時候,微信會向我們認(rèn)證(即之前配置的服務(wù)器地址)發(fā)送請求,配置服務(wù)器地址的時候向服務(wù)器發(fā)送的get請求,此時發(fā)送的post請求,請求地址相同。
2.處理請求返回信息
當(dāng)服務(wù)器端接收到請求時,需要驗證一下請求來源,即也需要配置服務(wù)器地址時的判斷,判斷成功,可以獲取用戶發(fā)送來的消息,并且返回給用戶信息
const token = opts.token
const {
signature,
nonce,
timestamp,
echostr
} = ctx.query
const str = [token, timestamp, nonce].sort().join('')
const sha = sha1(str)
if (sha !== signature) {
ctx.body = 'Failed'
return false
}
const data = await getRawBody(ctx.req, {
length: ctx.length,
limit: '1mb',
encoding: ctx.charset
})
const content = await util.parseXML(data)
console.log(content) //用戶向微信公眾號發(fā)送的消息
const replyBody = `哈哈哈,歡迎來的v家族.點擊<a >viho viho</a>`//定義用戶返回的信息
//注意這一段模版<與!之間不能有空格,如果有空格,向微信公眾號發(fā)送消息時會返回“該公眾號提供的服務(wù)出現(xiàn)故障,請稍后再試”
const xml = `<xml><ToUserName><![CDATA[${content.xml.FromUserName}]]></ToUserName><FromUserName><![CDATA[${content.xml.ToUserName}]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[${replyBody}]]></Content></xml>`
console.log('--replyBody', replyBody)
ctx.status = 200
ctx.type = 'application/xml'
ctx.body = xml
注意:
接收消息的格式和回復(fù)的格式不一樣,所以在判斷的時候會有區(qū)別??梢酝ㄟ^判斷接收到的消息格式或內(nèi)容作出處理,返回對應(yīng)的回復(fù)消息格式或內(nèi)容。
參考文檔如下:
接收消息
回復(fù)消息
四、JS-SDK
1.基本步驟:
步驟一:綁定域名
登錄微信公眾平臺進(jìn)入“公眾號設(shè)置”的“功能設(shè)置”里填寫“JS接口安全域名”
步驟二:引入JS文件
在需要調(diào)用JS接口的頁面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
步驟三:通過config接口注入權(quán)限驗證配置
wx.config({
debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
appId: '', // 必填,公眾號的唯一標(biāo)識
timestamp: , // 必填,生成簽名的時間戳
nonceStr: '', // 必填,生成簽名的隨機串
signature: '',// 必填,簽名
jsApiList: [] // 必填,需要使用的JS接口列表
});
步驟四:通過ready接口處理成功驗證
步驟五:通過error接口處理失敗驗證
2.簽名算法
備注:此部分若想使用現(xiàn)成的代碼測試,可以參考 微信開發(fā)總結(jié)
步驟三中涉及的appId、timestamp、nonceStr、signature 這四個參數(shù)是需要發(fā)送請求到后端服務(wù)器獲取的。
后端服務(wù)器需要做一個簽名才能生成signature。
具體實現(xiàn):
步驟一:獲取access_token
參考獲取access_token部分
步驟二:獲取jsapi_ticket
access_token 采用http GET方式請求獲得jsapi_ticket(有效期7200秒,開發(fā)者必須在自己的服務(wù)全局緩存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
步驟三:簽名算法
參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當(dāng)前網(wǎng)頁的URL,不包含#及其后面部分) 。對所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這里需要注意的是所有參數(shù)名均為小寫字符。對string1作sha1加密,字段名和字段值都采用原始值,不進(jìn)行URL 轉(zhuǎn)義。
參考代碼:
/**
* 創(chuàng)建隨機數(shù)
*/
function createNoncestr() {
return Math.random().toString(35).substring(2, 15)
}
/**
* 生成時間戳
*/
function createTimestamp() {
return parseInt((+new Date()) / 1000)
}
/**
* 簽名算法
*/
function signIt(args) {
const keys = Object.keys(args)
keys.sort()
let str = ''
keys.forEach(key => {
str += '&' + key.toLowerCase() + '=' + args[key]
})
str = str.substring(1)
console.log('str--', str)
const sha = sha1(str) //需要引入外部sha1依賴包
return sha
}
/**
* 簽名函數(shù)
* @param ticket
* @param url
* @returns {{noncestr: *, timestamp: *, signature: *}}
*/
function sign(ticket, url) {
const nonceStr = createNoncestr()
const timestamp = createTimestamp()
const signature = signIt({nonceStr, timestamp, jsapi_ticket: ticket, url})
return {
nonceStr,
timestamp,
signature
}
}
五、網(wǎng)頁授權(quán)、獲取用戶信息
1.類別
(1)以snsapi_base為scope發(fā)起的網(wǎng)頁授權(quán),用戶無感知,靜默授權(quán),但只能獲取到openid
(2)以snsapi_userinfo為scope發(fā)起的網(wǎng)頁授權(quán),彈出授權(quán)確認(rèn)頁面,用戶點擊確認(rèn)授權(quán)后才能獲取到用戶信息
注意:對于已關(guān)注公眾號的用戶,如果用戶從公眾號的會話或者自定義菜單進(jìn)入本公眾號的網(wǎng)頁授權(quán)頁,即使是scope為snsapi_userinfo,也是靜默授權(quán),用戶無感知。
2.基本流程
(1)在公眾中先設(shè)置授權(quán)回調(diào)域名

(2)用戶同意授權(quán),獲取code
可以讓用戶直接訪問下面的url地址,但是這個url過長,而且可以修改url中的參數(shù),因此最好向服務(wù)器端發(fā)起一個get請求,由服務(wù)器端重定向到下面地址。
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
用戶訪問上面這個地址,如果合法會跳轉(zhuǎn)redirect_uri參數(shù)值的地址,并在這個地址上加上code和state參數(shù)。
(3)通過code換取網(wǎng)頁授權(quán)access_token
注意:這里的access_token是專門用來獲取授權(quán)用戶信息使用的,與其他微信接口,需要通過基礎(chǔ)支持中的“獲取access_token”接口來獲取到的普通access_token是兩個不一樣的參數(shù),只是名字相同。
每個code只能使用一次。
(4)刷新access_token(如果需要)
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
(5)拉取用戶信息(需scope為 snsapi_userinfo)
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN