關鍵字:微信公眾平台 微信開放平台 微信登錄 移動應用微信登錄 使用微信賬號登錄APP
作者:方倍工作室
原文:http://www.cnblogs.com/txw1958/p/weixin-applogin.html
在這篇微信公眾平台開發教程中,我們將介紹如何使用微信開放平台接口實現移動應用微信登錄的功能。
移動應用微信登錄是基於OAuth2.0協議標准構建的微信OAuth2.0授權登錄系統。
在進行微信OAuth2.0授權登錄接入之前,在微信開放平台注冊開發者帳號,並擁有一個已審核通過的移動應用,並獲得相應的AppID和AppSecret,申請微信登錄且通過審核后,可開始接入流程。
1、目前移動應用上微信登錄只提供原生的登錄方式,需要用戶安裝微信客戶端才能配合使用。
2、對於Android應用,建議總是顯示微信登錄按鈕,當用戶手機沒有安裝微信客戶端時,請引導用戶下載安裝微信客戶端。
3、對於iOS應用,考慮到iOS應用商店審核指南中的相關規定,建議開發者接入微信登錄時,先檢測用戶手機是否已安裝微信客戶端(使用sdk中isWXAppInstalled函數 ),對未安裝的用戶隱藏微信登錄按鈕,只提供其他登錄方式(比如手機號注冊登錄、游客登錄等)。
授權流程說明
微信OAuth2.0授權登錄讓微信用戶使用微信身份安全登錄第三方應用或網站,在微信用戶授權登錄已接入微信OAuth2.0的第三方應用后,第三方可以獲取到用戶的接口調用憑證(access_token),通過access_token可以進行微信開放平台授權關系接口調用,從而可實現獲取微信用戶基本開放信息和幫助用戶實現基礎開放功能等。
微信OAuth2.0授權登錄目前支持authorization_code模式,適用於擁有server端的應用授權。該模式整體流程為:
1. 第三方發起微信授權登錄請求,微信用戶允許授權第三方應用后,微信會拉起應用或重定向到第三方網站,並且帶上授權臨時票據code參數;
2. 通過code參數加上AppID和AppSecret等,通過API換取access_token;
3. 通過access_token進行接口調用,獲取用戶基本數據資源或幫助用戶實現基本操作。
獲取access_token時序圖:
第一步:請求CODE
移動應用微信授權登錄
開發者需要配合使用微信開放平台提供的SDK進行授權登錄請求接入。正確接入SDK后並擁有相關授權域(scope,什么是授權域?)權限后,開發者移動應用會在終端本地拉起微信應用進行授權登錄,微信用戶確認后微信將拉起開發者移動應用,並帶上授權臨時票據(code)。
iOS平台應用授權登錄接入代碼示例(請參考iOS接入指南):
-(void)sendAuthRequest { //構造SendAuthReq結構體 SendAuthReq* req =[[[SendAuthReq alloc ] init ] autorelease ]; req.scope = @"snsapi_userinfo" ; req.state = @"123" ; //第三方向微信終端發送一個SendAuthReq消息結構 [WXApi sendReq:req]; }
Android平台應用授權登錄接入代碼示例(請參考Android接入指南):
{ // send oauth request Final SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "wechat_sdk_demo_test"; api.sendReq(req); }
參數說明
參數 | 是否必須 | 說明 |
---|---|---|
appid | 是 | 應用唯一標識,在微信開放平台提交應用審核通過后獲得 |
scope | 是 | 應用授權作用域,如獲取用戶個人信息則填寫snsapi_userinfo(什么是授權域?) |
state | 否 | 用於保持請求和回調的狀態,授權請求后原樣帶回給第三方。該參數可用於防止csrf攻擊(跨站請求偽造攻擊),建議第三方帶上該參數,可設置為簡單的隨機數加session進行校驗 |
返回示例:
appid: wxd477edab60670232
scope: snsapi_userinfo
state: wechat_sdk_demo
可拉起微信打開授權登錄頁:
返回說明
用戶點擊授權后,微信客戶端會被拉起,跳轉至授權界面,用戶在該界面點擊允許或取消,SDK通過SendAuth的Resp返回數據給調用方。
返回值 | 說明 |
---|---|
ErrCode | ERR_OK = 0(用戶同意) ERR_AUTH_DENIED = -4(用戶拒絕授權) ERR_USER_CANCEL = -2(用戶取消) |
code | 用戶換取access_token的code,僅在ErrCode為0時有效 |
state | 第三方程序發送時用來標識其請求的唯一性的標志,由第三方程序調用sendReq時傳入,由微信終端回傳,state字符串長度不能超過1K |
lang | 微信客戶端當前語言 |
country | 微信用戶當前國家信息 |
第二步:通過code獲取access_token
獲取第一步的code后,請求以下鏈接獲取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數說明
參數 | 是否必須 | 說明 |
---|---|---|
appid | 是 | 應用唯一標識,在微信開放平台提交應用審核通過后獲得 |
secret | 是 | 應用密鑰AppSecret,在微信開放平台提交應用審核通過后獲得 |
code | 是 | 填寫第一步獲取的code參數 |
grant_type | 是 | 填authorization_code |
返回如下
{ "access_token": "OezXcEiiBSKSxW0eoylIeOZ0dfxvb93UyrFdwznvwUv3JkVNVV1yFvQQa3IfuyMi4iZGDsAfe81sCaUXxyKrI-5XgCvhAS02eAC4MF2fJFl80Y9s-0h1EsuBmIVKgu0GnKhxCQ0M8G-gkQAJpzLzmQ", "expires_in": 7200, "refresh_token": "OezXcEiiBSKSxW0eoylIeOZ0dfxvb93UyrFdwznvwUv3JkVNVV1yFvQQa3IfuyMiH7dCabGFyMRtZHnHPHuEK78cf1eISYJ4y453T8pDa2tFAIJu8bFeLMBpeFSv9dgnGrK-ZfRxHzhq7IW4qevEMQ", "openid": "oH9d2v7NmDhsFzICG63UPSIOgUcY", "scope": "snsapi_userinfo", "unionid": "o4wcnwx0BVC4F_hSl5qCd5rC4Jps" }
參數說明
參數 | 說明 |
---|---|
access_token | 接口調用憑證 |
expires_in | access_token接口調用憑證超時時間,單位(秒) |
refresh_token | 用戶刷新access_token |
openid | 授權用戶唯一標識 |
scope | 用戶授權的作用域,使用逗號(,)分隔 |
unionid | 當且僅當該移動應用已獲得該用戶的userinfo授權時,才會出現該字段 |
獲取用戶個人信息(UnionID機制)
接口說明
此接口用於獲取用戶個人信息。開發者可通過OpenID來獲取用戶基本信息。特別需要注意的是,如果開發者擁有多個移動應用、網站應用和公眾帳號,可通過獲取用戶基本信息中的unionid來區分用戶的唯一性,因為只要是同一個微信開放平台帳號下的移動應用、網站應用和公眾帳號,用戶的unionid是唯一的。換句話說,同一用戶,對同一個微信開放平台下的不同應用,unionid是相同的。請注意,在用戶修改微信頭像后,舊的微信頭像URL將會失效,因此開發者應該自己在獲取用戶信息后,將頭像圖片保存下來,避免微信頭像URL失效后的異常情況。
請求說明
http請求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
參數說明
參數 | 是否必須 | 說明 |
---|---|---|
access_token | 是 | 調用憑證 |
openid | 是 | 普通用戶的標識,對當前開發者帳號唯一 |
lang | 否 | 國家地區語言版本,zh_CN 簡體,zh_TW 繁體,en 英語,默認為zh-CN |
{ "openid": "oH9d2v7NmDhsFzICG63UPSIOgUcY", "nickname": "方倍", "sex": 0, "language": "zh_CN", "city": "", "province": "", "country": "CN", "headimgurl": "http://wx.qlogo.cn/mmopen/pburdzLK7PUTcFw3ozK52Gravkznno51DSjnqnzsG6WzJLUOtadGBYYSVqh5YDicdawxrD6hHoR96OcyyDWAEgA/0", "privilege": [], "unionid": "o4wcnwx0BVC4F_hSl5qCd5rC4Jps" }
參數說明
參數 | 說明 |
---|---|
openid | 普通用戶的標識,對當前開發者帳號唯一 |
nickname | 普通用戶昵稱 |
sex | 普通用戶性別,1為男性,2為女性 |
province | 普通用戶個人資料填寫的省份 |
city | 普通用戶個人資料填寫的城市 |
country | 國家,如中國為CN |
headimgurl | 用戶頭像,最后一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空 |
privilege | 用戶特權信息,json數組,如微信沃卡用戶為(chinaunicom) |
unionid | 用戶統一標識。針對一個微信開放平台帳號下的應用,同一用戶的unionid是唯一的。 |
完整PHP SDK
class class_app { var $appid = APPID; var $appsecret = APPSECRET; //構造函數 public function __construct($appid = NULL, $appsecret = NULL) { if($appid && $appsecret){ $this->appid = $appid; $this->appsecret = $appsecret; } } //通過code獲取access_token public function oauth2_access_token($code) { $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->appsecret."&code=".$code."&grant_type=authorization_code"; $res = $this->http_request($url); return json_decode($res, true); } //獲取用戶個人信息(UnionID機制) public function oauth2_get_user_info($access_token, $openid) { $url = "https://api.weixin.qq.com/sns/userinfo?access_token=".$access_token."&openid=".$openid."&lang=zh_CN"; $res = $this->http_request($url); return json_decode($res, true); } //HTTP請求(支持HTTP/HTTPS,支持GET/POST) protected function http_request($url, $data = null) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); if (!empty($data)){ curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); $output = curl_exec($curl); curl_close($curl); return $output; } //日志記錄 private function logger($log_content) { if(isset($_SERVER['HTTP_APPNAME'])){ //SAE sae_set_display_errors(false); sae_debug($log_content); sae_set_display_errors(true); }else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL $max_size = 500000; $log_filename = "log.xml"; if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);} file_put_contents($log_filename, date('Y-m-d H:i:s').$log_content."\r\n", FILE_APPEND); } } }
調用方法
/* 方倍工作室 http://www.fangbei.org/ CopyRight 2014 All Rights Reserved 微信開放平台 移動應用 (微信登錄) */ header("Content-type: text/html; charset=utf-8"); define('APPID', "wx3f05f4b79761d123"); define('APPSECRET', "9acc222b92afb29cff90b9bcfc7d6080"); $code = "041359a1b393c92a5a509ce24e2ef50f"; $weixin = new class_app(); var_dump($weixin); //傳入授權臨時票據(code) $oauth2_info = $weixin->oauth2_access_token($code); var_dump($oauth2_info); $result = $weixin->oauth2_get_user_info($oauth2_info['access_token'], $oauth2_info['openid']); var_dump($result);