你為了給公眾號粉絲提供服務(wù),在菜單里加了一個(gè)網(wǎng)頁鏈接。點(diǎn)擊量不低,可用戶進(jìn)來后,你的業(yè)務(wù)系統(tǒng)仍然拿不到對方的任何身份標(biāo)識(shí)——下單查不到歷史記錄,領(lǐng)取優(yōu)惠券又要用戶手動(dòng)填手機(jī)號。這其實(shí)不算“打通”,只是放了一個(gè)外鏈。微信公眾號與網(wǎng)站、業(yè)務(wù)系統(tǒng)之間真正有效的連接,需要完成至少兩件事:在網(wǎng)頁端識(shí)別“這個(gè)用戶到底是誰”,以及讓業(yè)務(wù)事件能夠通過微信主動(dòng)觸達(dá)用戶。

一、把用戶身份串起來:網(wǎng)頁授權(quán)的關(guān)鍵路徑

微信公眾號與外部網(wǎng)站之間不存在自動(dòng)的身份傳遞。用戶從微信內(nèi)打開你的網(wǎng)頁時(shí),瀏覽器里并沒有攜帶微信號等標(biāo)識(shí)。你需要通過微信網(wǎng)頁授權(quán)(OAuth 2.0)來換取用戶的唯一標(biāo)識(shí)。

這個(gè)流程可以拆成四步:

  1. 構(gòu)造授權(quán)鏈接:引導(dǎo)用戶訪問一個(gè)由微信提供的 https://open.weixin.qq.com/connect/oauth2/authorize 地址,攜帶你的公眾號 appid、回調(diào) redirect_uri 以及授權(quán)類型參數(shù)。
  2. 用戶同意授權(quán):根據(jù) scope 參數(shù)的不同,分為靜默授權(quán)(snsapi_base,無需用戶感知,只能拿到 openid)和用戶信息授權(quán)(snsapi_userinfo,需用戶手動(dòng)確認(rèn),可以拿到昵稱、頭像等)。如果你的業(yè)務(wù)只是需要綁定用戶身份,優(yōu)先選擇靜默授權(quán),減少跳出。
  3. 換取 openid:用戶在微信內(nèi)確認(rèn)后,微信會(huì)將一個(gè)臨時(shí)的 code 附加到你的回調(diào)地址上。你的服務(wù)器需要用這個(gè) code,調(diào)用 https://api.weixin.qq.com/sns/oauth2/access_token 接口,換回 openid 和你公眾號此次授權(quán)的 access_token(注意:這是網(wǎng)頁授權(quán)專用的 access_token,與全局 access_token 不同)。
  4. 登錄你的業(yè)務(wù)系統(tǒng):拿到 openid 后,你的網(wǎng)站就可以在自己的用戶表里查找或新建對應(yīng)的賬號。至此,這名微信用戶在你的網(wǎng)站和業(yè)務(wù)系統(tǒng)中就有了唯一身份綁定。

下面是一個(gè)服務(wù)端發(fā)起換取 openid 的示例請求:

curl -X GET "https://api.weixin.qq.com/sns/oauth2/access_token?appid=YOUR_APPID&secret=YOUR_APPSECRET&code=CODE_FROM_CALLBACK&grant_type=authorization_code"

返回值中的 openid 是你業(yè)務(wù)系統(tǒng)中串聯(lián)用戶的核心字段,必須持久化存儲(chǔ),不要依賴網(wǎng)頁授權(quán)的 access_token 做長期身份維持,它的有效期很短且刷新規(guī)則脆弱。

二、讓業(yè)務(wù)系統(tǒng)“說話”:消息觸達(dá)的雙向通道

身份打通只是第一步。你需要讓用戶在你的網(wǎng)站或業(yè)務(wù)系統(tǒng)中的關(guān)鍵行為(如訂單狀態(tài)更新、工單處理完成),能夠通過公眾號主動(dòng)通知到用戶。這里依賴兩條路:模板消息客服消息。

  • 模板消息適用于固定格式的業(yè)務(wù)通知。你需要先在公眾號后臺(tái)申請模板,審核通過后獲得一個(gè)模板 ID。業(yè)務(wù)系統(tǒng)在需要發(fā)送通知時(shí),調(diào)用 https://api.weixin.qq.com/cgi-bin/message/template/send 接口,傳入用戶的 openid、模板 ID 以及對應(yīng)變量值。每個(gè)模板消息都有調(diào)用頻次限制和內(nèi)容審核規(guī)則,違規(guī)會(huì)被禁用。
  • 客服消息更靈活,適合非模板化的溝通場景,但僅能在用戶與公眾號產(chǎn)生過交互后 48 小時(shí)內(nèi)主動(dòng)推送。如果你的業(yè)務(wù)需要隨時(shí)聯(lián)系用戶,必須引導(dǎo)用戶先發(fā)送一條消息或點(diǎn)擊某個(gè)菜單,否則接口會(huì)返回 45015 錯(cuò)誤(回復(fù)時(shí)間超過限制)。

這兩條通道的共同前提是中控服務(wù)器必須持有全局 access_token。這個(gè) token 是調(diào)用絕大部分微信接口的憑證,使用 https://api.weixin.qq.com/cgi-bin/token 接口獲取,有效期 7200 秒。你需要設(shè)計(jì)一個(gè)集中刷新和緩存的機(jī)制,所有業(yè)務(wù)模塊都從這個(gè)緩存中讀取,防止因?yàn)槎喙?jié)點(diǎn)并發(fā)刷新導(dǎo)致舊 token 被覆蓋失效。

三、三個(gè)一踩就疼的落地細(xì)節(jié)

1. JS 接口安全域名不是可選項(xiàng)

如果你希望網(wǎng)頁內(nèi)調(diào)用微信內(nèi)置能力(如掃碼、分享、圖像處理),就必須把網(wǎng)頁域名添加到公眾號后臺(tái)的“JS 接口安全域名”中。一個(gè)常見誤區(qū)是只添加了主域名,卻忽略了 CDN 或靜態(tài)資源域名,導(dǎo)致部分 JS-SDK 調(diào)用失敗。此外,域名綁定時(shí)需要你將一個(gè)微信校驗(yàn)文件放置在網(wǎng)站根目錄下,且必須能夠通過公網(wǎng)直接訪問,不要做成后端路由跳轉(zhuǎn)。

2. 全局 access_token 的中控管理

不要在每個(gè)業(yè)務(wù)請求里都去重新獲取 access_token,也不要讓多個(gè)定時(shí)任務(wù)各自刷新。設(shè)計(jì)一個(gè)獨(dú)立的中控模塊,負(fù)責(zé)獲取、緩存、提前刷新并在失效時(shí)重試。示例刷新邏輯如下:

import requests
import time

TOKEN_CACHE = {"token": None, "expires_at": 0}

def get_access_token(appid, secret):
    if time.time() < TOKEN_CACHE["expires_at"] - 300:
        return TOKEN_CACHE["token"]
    resp = requests.get(
        "https://api.weixin.qq.com/cgi-bin/token",
        params={"grant_type": "client_credential", "appid": appid, "secret": secret}
    ).json()
    if "access_token" in resp:
        TOKEN_CACHE["token"] = resp["access_token"]
        TOKEN_CACHE["expires_at"] = time.time() + resp["expires_in"]
        return TOKEN_CACHE["token"]
    raise Exception("獲取 access_token 失敗")

3. 授權(quán)范圍與用戶信息的邊界

靜默授權(quán)只能拿到 openid。如果你的業(yè)務(wù)邏輯里寫了必須獲取用戶頭像昵稱,卻配置了 snsapi_base,回調(diào)拿不到用戶信息就會(huì)中斷流程。相反,如果你的頁面不需要顯示個(gè)人信息,就不要申請 snsapi_userinfo——每多一個(gè)不必要的授權(quán)彈窗,漏斗轉(zhuǎn)化率就會(huì)掉一截。從 2021 年起,微信對 snsapi_userinfo 拿到的頭像昵稱已經(jīng)不再保證實(shí)時(shí)性,如果需要展示用戶個(gè)性化信息,建議改用微信頭像昵稱獲取能力或者索性用自己的業(yè)務(wù)數(shù)據(jù)。

行動(dòng)清單

  1. 在業(yè)務(wù)用戶表中增加 openidunionid(如果需要跨應(yīng)用打通)字段,設(shè)計(jì)綁定與解綁流程。
  2. 搭建一個(gè)獨(dú)立的中控服務(wù),專門負(fù)責(zé) access_token 的刷新與分發(fā)。
  3. 優(yōu)先接入靜默授權(quán),完成用戶靜默登錄閉環(huán)后,再按頁面需求升級為顯式授權(quán)。
  4. 在后臺(tái)系統(tǒng)里將模板消息發(fā)送與業(yè)務(wù)事件解耦,通過消息隊(duì)列觸發(fā),方便后續(xù)擴(kuò)容和重試。
  5. 把 JS 安全域名配置和校驗(yàn)文件放置列為上線檢查項(xiàng),避免上線當(dāng)天才發(fā)現(xiàn)頁面無法調(diào)用微信能力。

微信公眾號與業(yè)務(wù)系統(tǒng)的連接,本質(zhì)是把微信的用戶標(biāo)識(shí)體系與你自己系統(tǒng)中的業(yè)務(wù)主鍵安全、穩(wěn)定地映射到一起,并讓服務(wù)端能在規(guī)則允許的窗口內(nèi)主動(dòng)觸達(dá)用戶。只要抓住網(wǎng)頁授權(quán)拿身份、中控管理保通信、消息通道做觸達(dá)這三點(diǎn),打通就不是技術(shù)難題,而是一個(gè)可以清晰落地的工程決策。

← 上一篇 分銷商城開發(fā)的合規(guī)雷區(qū):從一張罰單說起 下一篇 → 德清 SEO 優(yōu)化:為什么你在本地搜不到自己的廠,杭州的公司卻排在你前面?