微信公眾平台開發-OAuth2.0網頁授權接口、網頁授權接口詳解(含源碼)
作者: 孟祥磊-《微信公眾平台開發實例教程》
在微信開發的高級應用中,幾乎都會使用到該接口,因為通過該接口,可以獲取到用戶的微信基礎信息,其中的用戶唯一標識OpenID是微信應用中最長用到的參數之一,近期有很多學員一直咨詢,所以我寫下這篇文章。
1.網頁授權接口的作用
開發者通過網頁授權接口,可獲取到用戶的基本信息,包括OpenID、昵稱、用戶資料填寫的省份、城市、國家以及頭像地址,以實現業務邏輯。
與同樣是獲取用戶基本信息的用戶管理中的“獲取用戶信息”接口相比,網頁授權接口無論用戶是否關注了公眾號,都可以正常獲取到用戶信息,而用戶管理中的“獲取用戶信息”接口則必須關注公眾號才可獲取。
2.網頁授權接口模式介紹
微信公眾平台網頁授權接口有兩種模式,分別是scope為snsapi_base和scope為snsapi_userinfo,根據微信應用的不同需求,會用到不同的模式,兩種模式各有利弊。
(1)以snsapi_base為scope發起的網頁授權。
l 優點:靜默授權,直接跳轉到到回調頁,不會彈出“確認登陸”頁面,用戶感知較好
l 缺點:僅可獲取到用戶的OpenID,在需要獲取其他用戶信息時不適用
(2)以snsapi_userinfo為scope發起的網頁授權。
l 優點:除用戶OpenID外,還可以獲取到用戶的,昵稱、用戶資料填寫的省份、城市、國家以及頭像地址
l 缺點:用戶進入頁面時會彈出“確認登陸”也就是同意授權的頁面,單擊“確認登陸”按鈕后,才會跳轉到回調頁,用戶感知較差
注意:對於已關注該公眾號的用戶,如果從公眾號的回話或者自定義菜單進入本公眾號的網頁授權頁,即使是以snsapi_userinfo為scope發起的網頁授權,也是靜默授權,不會彈出“確認”登陸界面。
3.數據傳輸流程解析
以snsapi_base為scope發起的網頁授權,當用戶進入使用網頁授權的網頁時,會帶上code參數,通過該參數,並調用接口,可獲取到一個特殊的access_token以及用戶的OpenID,程序可根據該參數繼續運行,流程如圖所示。
以snsapi_userinfo為scope發起的網頁授權,與以snsapi_base為scope發起的網頁授權不同的是,首先會進入“確認登陸”,也就是授權頁面,用戶同意授權后,會跳轉到回調頁,並帶上code參數,通過該參數,並調用接口,可獲取到一個特殊的access_token以及用戶的OpenID,此時,scope為snsapi_userinfo時,即可通過access_token和OpenID獲取用戶的基本信息了。
4.網頁授權接口注意事項
(1)網頁授權接口暫時只支持認證后的服務號調用。
(2)在微信公眾號調用用戶網頁授權接口之前,開發者需要先到公眾平台官網中的“開發 → 接口權限 → 網頁服務 → 網頁帳號 → 網頁授權獲取用戶基本信息”的配置選項中,配置授權回調域名,如圖所示。請注意,這里填寫的是域名(是一個字符串),而不是URL,因此請勿加 http:// 等協議頭。
(3)授權回調域名配置規范為全域名,比如需要網頁授權的域名為:www.qq.com,如圖所示,配置以后此域名下面的頁面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以進行OAuth2.0鑒權。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com無法進行OAuth2.0鑒權。
(4)回調頁面域名需使用字母、數字及“-”的組合,不支持IP地址、端口號及短鏈。填寫的域名需與實際回調URL中的域名相同。填寫的域名須通過ICP備案的驗證。
5.scope參數為snsapi_base的網頁授權接口調用實例
步驟
(1)獲取code
(2)通過code換取access_token以及OpenID
(1)獲取code
在確保微信公眾賬號擁有授權作用域scope參數為snsapi_base的前提下,引導微信用戶打開如下格式頁面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
若提示“該鏈接無法訪問”,請檢查參數是否填寫錯誤,是否擁有scope參數對應的授權作用域權限。
參數說明,如表所示:
scope為snsapi_base時接口調用參數說明
參數 |
是否必須 |
說明 |
appid |
是 |
公眾號的唯一標識 |
redirect_uri |
是 |
授權后重定向的回調鏈接地址,請使用urlencode對鏈接進行處理 |
response_type |
是 |
返回類型,請填寫code |
scope |
是 |
應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid) |
state |
否 |
重定向后會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值,最多128字節 |
#wechat_redirect |
是 |
無論直接打開還是做頁面302重定向時候,必須帶此參數 |
訪問該鏈接后,會跳轉到回調頁,即redirect_uri/?code=CODE&state=STATE,如果回調頁是“http://www.xxx.qq/test.php”,code是微信自動分配的,也就是上面鏈接中獲取到的response_type的值,每次訪問都不同,假設code為“031cEhnA1qGrf10uzzoA1n3jnA1cEhn1”回調頁即為:
“http://www.xxx.qq/test.php/?code=031cEhnA1qGrf10uzzoA1n3jnA1cEhn1&state=STATE”。
(2)通過code換取access_token以及OpenID
回調頁帶上的code參數可通過GET方式獲取,即$_GET[‘code’];並通過指定接口地址獲取access_token以及OpenID。
接口調用地址:
調用參數說明,如表所示:
獲取access_token以及OpenID調用參數說明
參數 |
是否必須 |
說明 |
appid |
是 |
公眾號的唯一標識 |
secret |
是 |
公眾號的appsecret |
code |
是 |
填寫第一步獲取的code參數 |
grant_type |
是 |
填寫為authorization_code |
返回說明:
正常情況下,微信會返回JSON數據包給公眾號:
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE" }
返回參數說明:
返回參數說明
參數 |
描述 |
access_token |
網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同 |
expires_in |
access_token接口調用憑證超時時間,單位(秒) |
refresh_token |
用戶刷新access_token |
openid |
用戶唯一標識,請注意,在未關注公眾號時,用戶訪問公眾號的網頁,也會產生一個用戶和公眾號唯一的OpenID |
scope |
用戶授權的作用域,使用逗號(,)分隔 |
錯誤時微信會返回JSON數據包如下(示例為Code無效錯誤):
{"errcode":40029,"errmsg":"invalid code"}
5.程序
<?php /* 以snsapi_base為scope發起的網頁授權 獲取access_token,openid */ require('wei_function.php'); $appid="wx78478e595939c538"; $secret="5540e8ccab4f71dfad752f73cfb85780"; $code=$_GET['code']; $OAuthurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appid."&secret=".$secret."&code=".$code."&grant_type=authorization_code"; $OAuthinfo=json_decode(getdata($OAuthurl),true); //print_r($OAuthinfo); $access_token=$OAuthinfo['access_token']; $openid=$OAuthinfo['openid']; echo "獲取到的access_token:<br />".$access_token."<br />"; echo "獲取到的用戶openid:<br />".$openid; ?>
代碼解析
require('wei_function.php');該函數文件可以購買《微信公眾平台開發實例教程》,在該書中第95頁有詳細講解。
$appid="xxx";
$secret="xxx";
分別將公眾號的AppID和AppSecret賦值給變量$appid和$secret;
$OAuthurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appid."&secret=".$secret."&code=".$code."&grant_type=authorization_code";
$OAuthinfo=json_decode(getdata($OAuthurl),true);
$access_token=$OAuthinfo['access_token'];
$openid=$OAuthinfo['openid'];
將接口地址中的appid、secret和code參數替換,並通過getdata()函數(該函數在wei_function.php文件中,可直接被使用)請求該接口地址,並將返回的JSON數據通過json_decode()函數處理為數組,之后單獨輸出access_token和openid。
訪問該程序的網址為:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx78478e595939c538&redirect_uri=http://www.xxx.com/OAuth2.0.php&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
appid為公眾號的appid,且需與上面的$appid的值相同,否則會提示{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: z3H9UA0717ns83 ]"}這樣的錯誤信息,其代表的意思是不合法的oauth_code。
OAuth2.0.php為該程序文件。
運行效果如圖所示。
6.scope參數為snsapi_userinfo的網頁授權接口調用實例
步驟
(1)獲取code
(2)通過code換取access_token以及OpenID
(4)拉取用戶信息
(1)獲取code
在確保微信公眾賬號擁有授權作用域scope參數為snsapi_userinfo的前提下,引導微信用戶打開如下格式頁面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
若提示“該鏈接無法訪問”,請檢查參數是否填寫錯誤,是否擁有scope參數對應的授權作用域權限。
該鏈接格式與以snsapi_userinfo為scope發起的網頁授權不同的僅僅是scope不同,其余相同。
調用參數說明,如所示:
scope為snsapi_userinfo時接口調用參數說明
參數 |
是否必須 |
說明 |
appid |
是 |
公眾號的唯一標識 |
redirect_uri |
是 |
授權后重定向的回調鏈接地址,請使用urlencode對鏈接進行處理 |
response_type |
是 |
返回類型,請填寫code |
scope |
是 |
應用授權作用域,snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且,即使在未關注的情況下,只要用戶授權,也能獲取其信息) |
state |
否 |
重定向后會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值,最多128字節 |
#wechat_redirect |
是 |
無論直接打開還是做頁面302重定向時候,必須帶此參數 |
(2)通過code換取access_token以及OpenID
該步驟與以snsapi_userinfo為scope發起的網頁授權流程一致,參考其調用方法即可。
由於access_token擁有較短的有效期,當access_token超時后,可以使用refresh_token進行刷新,refresh_token有效期為30天,當refresh_token失效之后,需要用戶重新授權。
refresh_token在(2)通過code換取access_token以及OpenID中與access_token和OpenID一同獲取,獲取代碼為$refresh_token=$OAuthinfo['refresh_token'];。
(4)拉取用戶信息
<?php /* 以snsapi_base為scope發起的網頁授權 獲取access_token,openid */ require('wei_function.php'); $appid="wx78478e595939c538"; $secret="5540e8ccab4f71dfad752f73cfb85780"; $code=$_GET['code']; $OAuthurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appid."&secret=".$secret."&code=".$code."&grant_type=authorization_code"; $OAuthinfo=json_decode(getdata($OAuthurl),true); //print_r($OAuthinfo); $access_token=$OAuthinfo['access_token']; $openid=$OAuthinfo['openid']; $user_url="https://api.weixin.qq.com/sns/userinfo?access_token=".$access_token."&openid=".$openid."&lang=zh_CN"; $user_info=json_decode(getdata($user_url),true); //print_r($user_info); echo "OpenID:".$user_info['openid']; echo "<br />"; echo "昵稱:".$user_info['nickname']; echo "<br />"; echo "性別:".$user_info['sex']; echo "<br />"; echo "資料填寫城市:".$user_info['city']; echo "<br />"; echo "資料填寫省份:".$user_info['province']; echo "<br />"; echo "資料填寫國家:".$user_info['country']; echo "<br />"; echo "用戶頭像地址:".$user_info['headimgurl']; echo "<br />"; echo "unionid:".$user_info['unionid']; ?>
效果如圖所示:
點此購買《微信公眾平台開發實例教程》