使用koa2開發(fā)微信公眾號之網(wǎng)頁授權(quán)

最近做需求要對接微信公眾號,看了兩天文檔,基本算是理清楚了,在這里做下記錄。

準(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)的域名地址,因為獲取用戶信息是微信提供的鏈接,獲取后需要再重定向到我們自己的頁面。

  1. 使用之前需要到公眾號里把我們的域名設(shè)置成網(wǎng)頁授權(quán)域名。
    設(shè)置方法:登錄微信公眾平臺 > 設(shè)置 > 公眾號設(shè)置 > 功能設(shè)置 > 網(wǎng)頁授權(quán)域名

  2. 配置規(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獲取用戶信息
  1. 跳轉(zhuǎn)到我們自己的頁面以后,url中會自動添加code。
    示例:http://test.raydom.wang/?code=081tRRYX1Bk2IT0JNqVX16RAYX1tRRYT&state=123

  2. 獲取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)
    })

  1. 在后臺用拿到的 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)
        })
})
  1. 刷新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>
  1. 如果開發(fā)者擁有多個移動應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號,可通過獲取用戶基本信息中的unionid來區(qū)分用戶的唯一性,因為同一用戶,對同一個微信開放平臺下的不同應(yīng)用(移動應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號),unionid是相同的。

  2. 獲取 unionid 需要 scope 使用 snsapi_userinfo。

檢驗授權(quán)憑證(access_token)是否有效

請求接口: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"}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • title: 微信公眾號開發(fā):獲取openId和用戶信息 tags: 微信公眾號 categories: 筆記 ...
    行徑行閱讀 141,983評論 5 63
  • 微信服務(wù)號開發(fā) 整體流程 域名報備,服務(wù)器搭建 Python開發(fā)環(huán)境和項目的初始化搭建; 微信公眾號注冊及開發(fā)模式...
    飛行員suke閱讀 4,690評論 0 14
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,765評論 25 709
  • 一、公眾號介紹 微信公眾號分類 訂閱號:主要偏于為用戶傳達(dá)資訊(類似報紙雜志),認(rèn)證前后都是每天只可以群發(fā)一條消息...
    小花的胖次閱讀 6,824評論 3 37
  • 過去一段時間曾在無數(shù)個夜里被夢驚醒 滿身是汗。醒了嚇得不敢再睡,也害怕黑夜的到來,一個人無法熬過,不能入眠。 過去...
    春風(fēng)十里w閱讀 370評論 0 2

友情鏈接更多精彩內(nèi)容