微信開發(fā)

微信有4種類型的服務(wù):

  • 訂閱號祟印,針對媒體和個人,偏向于向用戶傳達咨詢即發(fā)消息(一般是推文)粟害,每天可以群發(fā)一條消息蕴忆,消息被放在“訂閱號消息”欄中。
  • 服務(wù)號悲幅,針對企業(yè)和組織套鹅,偏向于交互服務(wù),因為偏向于服務(wù)汰具,所以每月只能發(fā)4次推文卓鹿。
  • 企業(yè)號,所有功能都支持
  • 小程序

訂閱號和服務(wù)號在開發(fā)者接口權(quán)限上有所不同郁副,服務(wù)號更全面滋尉。不過對于一些基本的接口權(quán)限律歼,訂閱號都能滿足,具體可以參考權(quán)限接口說明

對于有支付需求的應(yīng)用和蚪,不管是服務(wù)號還是訂閱號都需要做支付申請,但是盡量選擇服務(wù)號遭铺。

出于用戶體驗和安全性方面的考慮搀绣,微信公眾號的注冊有一定門檻,某些高級接口的權(quán)限需要微信認證后才可以獲取恰聘。所以句各,為了幫助開發(fā)者快速了解和上手微信公眾號開發(fā)吸占,熟悉各個接口的調(diào)用,微信推出了微信公眾帳號測試號凿宾,通過手機微信掃描二維碼即可獲得測試號矾屯。

接入微信公眾平臺

環(huán)境準(zhǔn)備:

  • 公眾平臺測試賬號(參考上一節(jié))
  • 內(nèi)網(wǎng)映射,在接入公眾平臺時初厚,需要提供服務(wù)器的URL地址件蚕,這里使用Natapp做內(nèi)網(wǎng)映射

natapp隧道搭建

微信公眾平臺開發(fā)者模式需要提供服務(wù)器的URL地址,這里使用NATAPP做內(nèi)網(wǎng)穿透产禾。

打開NATAPP官網(wǎng)排作,注冊登錄后,點擊購買隧道亚情,可以使用免費隧道妄痪,也可購買付費隧道。免費隧道與付費隧道不同的是楞件,付費隧道支持固定的二級域名(當(dāng)然衫生,這個二級域名也是需要你購買的),這樣我們每次啟動natapp做內(nèi)網(wǎng)穿透時履因,域名不會改變的障簿,方便調(diào)試。

購買隧道后栅迄,我們做客戶端的配置站故,這里我是Mac環(huán)境,其他環(huán)境參考官網(wǎng)毅舆。

下載natapp客戶端西篓,添加執(zhí)行權(quán)限

# 解壓
?  Desktop unzip natapp_darwin_amd64_2_3_9.zip 
Archive:  natapp_darwin_amd64_2_3_9.zip
  inflating: natapp  
# 移動natapp到natapp目錄下
?  Desktop mkdir ~/natapp && mv natapp ~/natapp/
?  Desktop cd ~/natapp 
?  natapp chmod +x natapp 

運行natapp

./natapp -authtoken=xxxxxxxxxx

authtoken的值在我的隧道列表中可以查看。至此憋活,natapp隧道搭建完成岂津,總的流程如下:

  • 購買隧道(可以使用免費的隧道),設(shè)置域名和本地應(yīng)用端口
  • 在本地啟動natapp客戶端做穿透

配置后臺服務(wù)器信息

微信服務(wù)器使用應(yīng)用服務(wù)器配置信息來與其做交互悦即,配置信息主要包括URL地址吮成、token和EncodingAESKey,其中:

  • URL 是應(yīng)用服務(wù)器的地址辜梳,它是微信服務(wù)器與應(yīng)用服務(wù)器的交互入口粱甫,公眾號產(chǎn)生的任何消息(如用戶關(guān)注該公眾號,或用戶向公眾號發(fā)送消息等)作瞄,都會調(diào)用該地址通知應(yīng)用服務(wù)器茶宵。
  • token 表示令牌,在填寫了URL地址后宗挥,微信服務(wù)器需要驗證該地址是否有效乌庶,這是就需要用到這個token
  • EncodingAESKey 消息加密密鑰种蝶,用戶在公眾號上產(chǎn)生的所有事件,都會以消息的形式發(fā)送了上面的URL地址瞒大,這個消息可以選擇加密螃征,這個EncodingAESKey就是消息加密的密鑰。
image-20200326151044920.png

編寫服務(wù)器驗證接口

微信會驗證我們提供的服務(wù)器URL是否有效糠赦,具體流程如下:

  • 微信服務(wù)器向URL發(fā)送GET請求
  • 服務(wù)器驗證該請求会傲,并返回指定的值

GET請求附帶了一些參數(shù),包括:

  • signature 簽名拙泽,作為我們驗證結(jié)果的比對
  • timestamp 時間戳,驗證參數(shù)之一
  • nonce 隨機數(shù)裸燎,驗證參數(shù)之一
  • echostr 如果成功返回該參數(shù)

具體的驗證算法偽代碼如下:

if(sha1(token+timestamp+nonce) == signature){
  return echostr;
}
return "";

將token顾瞻、timestamp和nonce按順序組成一個字符串,使用sha1加密德绿。如果加密后的字符串與signature相同荷荤,則返回echostr。微信服務(wù)器在收到echostr后移稳,表示該開發(fā)服務(wù)器已經(jīng)接入了微信服務(wù)器蕴纳。

@RestController
@RequestMapping("/auth/wechat")
public class WeChatMakeController {

    @GetMapping("/mkserver")
    public String makeServer(String signature,
                             String timestamp,
                             String nonce,
                             String echostr){
        return echostr;
    }
}

這里為了方面,我直接返回了echostr个粱。

獲取access_token

調(diào)用各微信接口時都需使用access_token古毛,access_token的有效期目前為2個小時,需定時刷新都许,每天只能刷新2000次稻薇,接口為GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET。一般的處理方式是胶征,將access_token存儲在內(nèi)存的某一個地方(實例或redis中)統(tǒng)一管理塞椎。向外提供獲取access_token的方法,方法內(nèi)部需要考慮token過期與多線程的情況睛低。參考me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl#getAccessToken

public String getAccessToken(boolean forceRefresh) throws WxErrorException {
    // 微信配置存儲器
    final WxMpConfigStorage config = this.getWxMpConfigStorage();
    // 是否獲取 或 強制刷新
    if (!config.isAccessTokenExpired() && !forceRefresh) {
      // 未過期直接返回數(shù)據(jù)
      return config.getAccessToken();
    }

    // 多線程情況
    Lock lock = config.getAccessTokenLock();
    lock.lock();
    try {
      if (!config.isAccessTokenExpired() && !forceRefresh) {
        return config.getAccessToken();
      }
      // 調(diào)用微信接口獲取access_token
      // 更新存儲器中的token
      // 返回token
     
    } finally {
      lock.unlock();
    }
}

配置菜單

公眾號下的菜單欄最多包括3個一級菜單案狠,每個一級菜單最多包含5個二級菜單。菜單有多種類型

  • click 點擊事件
  • view 跳轉(zhuǎn)url
  • miniprogram 跳轉(zhuǎn)到小程序
  • scancode_push 掃碼推事件
  • scancode_waitmsg 掃碼推事件且彈出“消息接收中”提示框.
  • pic_sysphoto 彈出系統(tǒng)拍照發(fā)圖
  • pic_photo_or_album 彈出拍照或者相冊發(fā)圖
  • pic_weixin 彈出微信相冊發(fā)圖器
  • location_select 彈出地理位置選擇器
  • location_select 彈出地理位置選擇器
  • media_id 下發(fā)消息(除文本消息)
  • view_limited 跳轉(zhuǎn)圖文消息URL

其中最常用的是click钱雷、view和miniprogram骂铁。不同的菜單類型需要加的不同的參數(shù),比如急波,view類型的菜單是跳轉(zhuǎn)url的从铲,所以,我們需要附加url項澄暮。而click類型的菜單名段,我們需要附加一個key阱扬,以標(biāo)識該菜單。

 {
     // button代表的是菜單欄伸辟,是一個數(shù)組麻惶,里面的元素表示菜單
     "button":[
       // click類型的菜單,使用key標(biāo)識該菜單信夫,方便后臺處理對應(yīng)的業(yè)務(wù)
       {    
            "type":"click",
            "name":"今日歌曲",
            "key":"V1001_TODAY_MUSIC"
        },
       // view類型的菜單窃蹋,url表示要跳轉(zhuǎn)的地址
        {   
           "type":"view",
           "name":"搜索",
           "url":"http://www.soso.com/"
        },
       // 使用子菜單,sub_button是一個數(shù)組静稻,里面的元素是其子菜單
        {
          "name":"其他",
          "sub_button": []
        }
     ]
 }

生成菜單時警没,需要向以下地址發(fā)送post請求

https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN

獲取用戶信息

公眾號獲取用戶信息有兩種方式,通過openid獲取以及通過OAuth2獲取振湾。

通過OpenID獲取用戶信息

當(dāng)用戶關(guān)注公眾號后杀迹,微信服務(wù)器會為該用戶對于公眾號產(chǎn)生一個openid,這個openid是唯一的押搪,同一個用戶在不同的公眾號中openid是不同的树酪。后臺可根據(jù)該openid來獲取用戶信息。

GET https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

access_token是我們上面章節(jié)介紹獲取的大州。openid是微信服務(wù)器向后臺配置的URL發(fā)送的請求參數(shù)续语,比如,當(dāng)用戶關(guān)注了公眾號厦画,微信服務(wù)器會調(diào)用后臺的url地址疮茄,其中FromUserName就是該用戶的OpenID。

通過OAuth2獲取用戶信息

1 訂閱號不能使用該接口苛白,服務(wù)號需要認證后才能使用該接口

2 必須使用微信內(nèi)置瀏覽器

關(guān)于OAuth2.0 授權(quán)可以參考阮一峰的理解OAuth 2.0娃豹,因為這里采用的是OAuth2.0的授權(quán)碼模式,所以這里簡要的說一下使用授權(quán)碼模式的步驟购裙。

  1. 獲取授權(quán)碼(code)
  2. 使用code換access_token
  3. 獲取用戶信息

獲取授權(quán)碼

獲取授權(quán)碼的地址如下:

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

  • redirect_uri 為微信授權(quán)后的回調(diào)頁懂版,該回調(diào)頁的域名部分需要在公眾號的后臺設(shè)置(接口權(quán)限/網(wǎng)頁授權(quán))

    注意:在公眾號后臺設(shè)置的回調(diào)地址時,填寫的是域名躏率,而不是URL躯畴,因此請勿加 http:// 等協(xié)議頭。

  • response_type 授權(quán)類型薇芝,這里填固定值code蓬抄,因為微信采用的是OAuth2.0的授權(quán)碼模式

  • scope 授權(quán)的作用域,有兩種取值

    snsapi_base snsapi_userinfo
    用戶信息 用戶的OpenID 用戶基本信息(昵稱夯到、頭像等)
    感知度 用戶無感知嚷缭,直接進入回調(diào)頁 1 用戶未關(guān)注公眾號,彈出授權(quán)頁面,用戶手動授權(quán)<br />2 用戶已關(guān)注公眾號阅爽,且通過點擊公眾號的菜單進入路幸,無需授權(quán)頁,即無感知

    由上可以看出付翁,用戶即使未關(guān)注公眾號(已認證的服務(wù)號)简肴,也可以獲取用戶信息。

  • state 表示客戶端的狀態(tài)百侧,微信服務(wù)器會原封不動的返回該值

獲取access_token

注意這里的網(wǎng)頁授權(quán)access_token與前面所講的access_token是不同的砰识,這里的access_token只適合在OAuth2.0授權(quán)流程中使用。

通過第一步后佣渴,微信服務(wù)器會調(diào)用回調(diào)也的地址辫狼,并附帶code和state兩個參數(shù)

redirect_uri/?code=CODE&state=STATE。

回調(diào)頁使用這個code從微信服務(wù)器上獲取access_token辛润。這一步是后臺服務(wù)器和微信服務(wù)器做交互予借,可以認為是安全的通信。

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID
&secret=SECRET
&code=CODE
&grant_type=authorization_code
  • appid 公眾號的appid
  • secret 公眾號的appsecret
  • code 第一步獲取的code
  • grant_type 授權(quán)類型频蛔,授權(quán)碼模式,所以這里是固定值authorization_code

返回如下信息

{
  "access_token":"訪問token",
  "expires_in":7200,
  "refresh_token":"刷新token",
  "openid":"OPENID",
  "scope":"SCOPE" 
}

當(dāng)用戶未關(guān)注公眾號時秦叛,訪問公眾號的網(wǎng)頁晦溪,也會產(chǎn)生OpenID,且這個OpenID與關(guān)注后的OpenID相同挣跋。

獲取用戶信息

使用以下地址獲取用戶信息

https://api.weixin.qq.com/sns/userinfo?
access_token=ACCESS_TOKEN
&openid=OPENID
&lang=zh_CN
  • access_token 訪問令牌三圆,上一步得到
  • openid 用戶的唯一標(biāo)識,上一步得到

返回的用戶信息

{   
  "openid":" OPENID",
  "nickname": "NICKNAME",
  "sex":"1男避咆,2女舟肉,0未知",
  "province":"PROVINCE",
  "city":"CITY",
  "country":"COUNTRY",
  "headimgurl": "headimgurl",
  "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
  "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

前后端分離獲取用戶信息

先后端分離時,微信登錄的解決辦法:

  • 前端請求微信的code
  • 收到code后查库,將code發(fā)送給后端
  • 后端通過code換取access-token
  • 通過access-token路媚,獲取當(dāng)前登錄的用戶信息,返回給前端
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末樊销,一起剝皮案震驚了整個濱河市整慎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌围苫,老刑警劉巖裤园,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異剂府,居然都是意外死亡拧揽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淤袜,“玉大人痒谴,你說我怎么就攤上這事∫樱” “怎么了闰歪?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蓖墅。 經(jīng)常有香客問我库倘,道長,這世上最難降的妖魔是什么论矾? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任教翩,我火速辦了婚禮,結(jié)果婚禮上贪壳,老公的妹妹穿的比我還像新娘饱亿。我一直安慰自己,他們只是感情好闰靴,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布彪笼。 她就那樣靜靜地躺著,像睡著了一般蚂且。 火紅的嫁衣襯著肌膚如雪配猫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天杏死,我揣著相機與錄音泵肄,去河邊找鬼。 笑死淑翼,一個胖子當(dāng)著我的面吹牛腐巢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玄括,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼冯丙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惠豺?” 一聲冷哼從身側(cè)響起银还,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洁墙,沒想到半個月后蛹疯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡热监,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年捺弦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡列吼,死狀恐怖幽崩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情寞钥,我是刑警寧澤慌申,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站理郑,受9級特大地震影響蹄溉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜您炉,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一柒爵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赚爵,春花似錦棉胀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至窝剖,卻和暖如春驮瞧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枯芬。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留采郎,地道東北人千所。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像蒜埋,于是被迫代替她去往敵國和親淫痰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容