最近做需求要對接微信公眾號,看了兩天文檔,基本算是理清楚了,在這里做下記錄。
準(zhǔn)備工作
了解公眾號類型和接口權(quán)限
微信公眾號分為訂閱號和服務(wù)號,兩種賬號都可以進(jìn)行微信認(rèn)證以獲取更多接口權(quán)限(個人注冊的訂閱號不能進(jìn)行微信認(rèn)證)。
具體接口權(quán)限見:官方文檔 >>
獲取微信公眾平臺測試號
如果沒有申請好的公眾號,可以使用官方提供的測試賬號,使用自己微信號掃描登錄即可。
登錄地址:微信公眾平臺測試號 >>
網(wǎng)頁授權(quán)回調(diào)域名設(shè)置
我們要想在我們的網(wǎng)頁中獲取用戶信息,就必須通過網(wǎng)頁授權(quán)來實現(xiàn)。網(wǎng)頁回調(diào)域名是指獲取用戶信息后需要跳轉(zhuǎn)的域名地址,因為獲取用戶信息是微信提供的鏈接,獲取后需要再重定向到我們自己的頁面。
使用之前需要到公眾號里把我們的域名設(shè)置成網(wǎng)頁授權(quán)域名。
設(shè)置方法:登錄微信公眾平臺 > 設(shè)置 > 公眾號設(shè)置 > 功能設(shè)置 > 網(wǎng)頁授權(quán)域名配置規(guī)范為全域名(不需要加
http://或https://),設(shè)置后可以在該域名下所有的頁面使用,但不能在該域名的二級域名下使用。
如:設(shè)置了
www.raydom.wang,http://www.raydom.wang/index.html中可以使用,但http://note.raydom.wang中不能使用。
后臺環(huán)境搭建
為了安全起見,微信的接口調(diào)用都需要放到后臺進(jìn)行。這里使用的是基于node環(huán)境的koa2服務(wù)環(huán)境。
開始
第一步:用戶同意授權(quán),獲取code
引導(dǎo)用戶打開如下鏈接:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
參數(shù)說明:
| 參數(shù) | 必填 | 說明 |
|---|---|---|
| appid | 是 | 公眾號的唯一標(biāo)識 |
| redirect_uri | 是 | 授權(quán)后重定向的回調(diào)鏈接地址, 請使用 urlEncode 對鏈接進(jìn)行處理 |
| response_type | 是 | 返回類型,請?zhí)顚慶ode |
| scope | 是 | 應(yīng)用授權(quán)作用域,snsapi_base (不彈出授權(quán)頁面,直接跳轉(zhuǎn),只能獲取用戶openid),snsapi_userinfo (彈出授權(quán)頁面,可通過openid拿到昵稱、性別、所在地。并且, 即使在未關(guān)注的情況下,只要用戶授權(quán),也能獲取其信息 ) |
| state | 否 | 重定向后會帶上state參數(shù),開發(fā)者可以填寫a-zA-Z0-9的參數(shù)值,最多128字節(jié) |
| #wechat_redirect | 是 | 無論直接打開還是做頁面302重定向時候,必須帶此參數(shù) |
注意:redirect_uri 的值需要經(jīng)過 urlEncode 處理。
js中沒有提供原生方法,可以使用工具處理以后使用: urlEncode處理工具 >>
如果用戶關(guān)注了公眾號,
scope使用snsapi_userinfo獲取用戶信息時,也不會彈出授權(quán)框(測試公眾號每次都會彈)
第二步:通過code獲取用戶信息
跳轉(zhuǎn)到我們自己的頁面以后,url中會自動添加code。
示例:http://test.raydom.wang/?code=081tRRYX1Bk2IT0JNqVX16RAYX1tRRYT&state=123獲取url中的code到后臺
前端代碼示例:
// 獲取url中的參數(shù)
function GetQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
// 這里使用的axios進(jìn)行ajax請求
axios.get("http://testapi.raydom.wang/login", {
params: {
code: GetQueryString("code")
}
})
.then((res) => {
console.log(res)
})
- 在后臺用拿到的
code獲取ACCESS_TOKEN、openid和更多信息
后臺代碼示例:
const router = require('koa-router')() // 引入router
const superagent = require('superagent') // 一個node環(huán)境http(s)請求中間件
const cache = require('memory-cache') // 緩存處理中間件
const appid = "xxxxxxxxxxxxxxx" // appid
const appsecret = "xxxxxxxxxxxxxxxxxxx" // appsecret
router.get("/login", async(ctx, next) => {
let ACCESS_TOKEN = "",
openid = "";
// 使用code獲取openid和access_token
await superagent
.get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" +
appid + "&secret=" +
appsecret + "&code=" +
ctx.query.code + "&grant_type=authorization_code")
.then(res => {
// 此處本來應(yīng)該用res.body獲取返回的json數(shù)據(jù),但總是獲取不到,只能用text代替
let result = JSON.parse(res.text)
ACCESS_TOKEN = result.access_token
openid = result.openid
})
.catch(res => {
console.log(res)
})
// 使用ACCESS_TOKEN和openid
await superagent
.get("https://api.weixin.qq.com/sns/userinfo?access_token=" +
access_token + "&openid=" + openid + "&lang=zh_CN")
.then(res => {
console.log(JSON.parse(res.text))
ctx.body = {
state: 1,
msg: '獲取access_token成功!'
}
})
.catch(res => {
console.log(res)
})
})
- 刷新access_token(如果需要)
由于access_token擁有較短的有效期,當(dāng)access_token超時后,可以使用refresh_token進(jìn)行刷新,refresh_token有效期為30天,當(dāng)refresh_token失效之后,需要用戶重新授權(quán)。
請求方法:
獲取第二步的refresh_token后,請求以下鏈接獲取access_token:https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
返回結(jié)果:
| 參數(shù) | 描述 |
|---|---|
| access_token | 網(wǎng)頁授權(quán)接口調(diào)用憑證,注意:此access_token與基礎(chǔ)支持的access_token不同 |
| expires_in | access_token接口調(diào)用憑證超時時間,單位(秒) |
| refresh_token | 用戶刷新access_token |
| openid | 用戶唯一標(biāo)識 |
| scope | 用戶授權(quán)的作用域,使用逗號(,)分隔 |
關(guān)于UnionID機(jī)制(測試賬號無法獲?。?/h5>
如果開發(fā)者擁有多個移動應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號,可通過獲取用戶基本信息中的unionid來區(qū)分用戶的唯一性,因為同一用戶,對同一個微信開放平臺下的不同應(yīng)用(移動應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號),unionid是相同的。
獲取 unionid 需要 scope 使用 snsapi_userinfo。
檢驗授權(quán)憑證(access_token)是否有效
如果開發(fā)者擁有多個移動應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號,可通過獲取用戶基本信息中的unionid來區(qū)分用戶的唯一性,因為同一用戶,對同一個微信開放平臺下的不同應(yīng)用(移動應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號),unionid是相同的。
獲取 unionid 需要 scope 使用 snsapi_userinfo。
請求接口:http:GET(請使用https協(xié)議) https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
有效返回的JSON結(jié)果:
{ "errcode":0,"errmsg":"ok"}
錯誤時的JSON返回示例:
{ "errcode":40003,"errmsg":"invalid openid"}