一、什么是OAuth2.0
官方網(wǎng)站:http://oauth.net/ ??http://oauth.net/2/
權威定義:OAuth is An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.
OAuth是一個開放協(xié)議,允許用戶讓第三方應用以安全且標準的方式獲取該用戶在某一網(wǎng)站、移動或桌面應用上存儲的私密的資源(如用戶個人信息、照片、視頻、聯(lián)系人列表),而無需將用戶名和密碼提供給第三方應用。
OAuth 2.0是OAuth協(xié)議的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0關注客戶端開發(fā)者的簡易性,同時為Web應用,桌面應用和手機,和起居室設備提供專門的認證流程。
OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數(shù)據(jù)。每一個令牌授權一個特定的網(wǎng)站(例如,視頻編輯網(wǎng)站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth允許用戶授權第三方網(wǎng)站訪問他們存儲在另外的服務提供者上的信息,而不需要分享他們的訪問許可或他們數(shù)據(jù)的所有內容。
新浪微博API目前也使用OAuth 2.0。
二、微信公眾平臺OAuth2.0授權
微信公眾平臺OAuth2.0授權詳細步驟如下:
1. 用戶關注微信公眾賬號。
2. 微信公眾賬號提供用戶請求授權頁面URL。
3. 用戶點擊授權頁面URL,將向服務器發(fā)起請求
4. 服務器詢問用戶是否同意授權給微信公眾賬號(scope為snsapi_base時無此步驟)
5. 用戶同意(scope為snsapi_base時無此步驟)
6. 服務器將CODE通過回調傳給微信公眾賬號
7. 微信公眾賬號獲得CODE
8. 微信公眾賬號通過CODE向服務器請求Access Token
9. 服務器返回Access Token和OpenID給微信公眾賬號
10. 微信公眾賬號通過Access Token向服務器請求用戶信息(scope為snsapi_base時無此步驟)
11. 服務器將用戶信息回送給微信公眾賬號(scope為snsapi_base時無此步驟)
如果用戶在微信中(Web微信除外)訪問公眾號的第三方網(wǎng)頁,公眾號開發(fā)者可以通過此接口獲取當前用戶基本信息(包括昵稱、性別、城市、國家)。利用用戶信息,可以實現(xiàn)體驗優(yōu)化、用戶來源統(tǒng)計、帳號綁定、用戶身份鑒權等功能。請注意,“獲取用戶基本信息接口是在用戶和公眾號產生消息交互時,才能根據(jù)用戶OpenID獲取用戶基本信息,而網(wǎng)頁授權的方式獲取用戶基本信息,則無需消息交互,只是用戶進入到公眾號的網(wǎng)頁,就可彈出請求用戶授權的界面,用戶授權后,就可獲得其基本信息(此過程甚至不需要用戶已經關注公眾號。)”
微信OAuth2.0授權登錄讓微信用戶使用微信身份安全登錄第三方應用或網(wǎng)站,在微信用戶授權登錄已接入微信OAuth2.0的第三方應用后,第三方可以獲取到用戶的接口調用憑證(access_token),通過access_token可以進行微信開放平臺授權關系接口調用,從而可實現(xiàn)獲取微信用戶基本開放信息和幫助用戶實現(xiàn)基礎開放功能等。
在微信公眾號請求用戶網(wǎng)頁授權之前,開發(fā)者需要先到公眾平臺網(wǎng)站的我的服務頁中配置授權回調域名。請注意,這里填寫的域名不要加http://
關于配置授權回調域名的說明:
授權回調域名配置規(guī)范為全域名,比如需要網(wǎng)頁授權的域名為: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鑒權。
具體而言,網(wǎng)頁授權流程分為四步:
引導用戶進入授權頁面同意授權,獲取code
通過code換取網(wǎng)頁授權access_token(與基礎支持中的access_token不同)
如果需要,開發(fā)者可以刷新網(wǎng)頁授權access_token,避免過期
通過網(wǎng)頁授權access_token和openid獲取用戶基本信息
[隱藏]
2第二步:通過code換取網(wǎng)頁授權access_token
4第四步:拉取用戶信息(需scope為 snsapi_userinfo)
在確保微信公眾賬號擁有授權作用域(scope參數(shù))的權限的前提下(服務號獲得高級接口后,默認帶有scope參數(shù)中的snsapi_base和snsapi_userinfo),引導關注者打開如下頁面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
?若提示“該鏈接無法訪問”,請檢查參數(shù)是否填寫錯誤,是否擁有scope參數(shù)對應的授權作用域權限。
參考鏈接(請在微信客戶端中打開此鏈接體驗)?Scope為snsapi_base
?https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=http%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect?Scope為snsapi_userinfo?https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
參數(shù)說明
參數(shù)是否必須說明
appid是公眾號的唯一標識
redirect_uri是授權后重定向的回調鏈接地址,請使用urlencode對鏈接進行處理
response_type是返回類型,請?zhí)顚慶ode
scope是應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。并且,即使在未關注的情況下,只要用戶授權,也能獲取其信息)
state否重定向后會帶上state參數(shù),開發(fā)者可以填寫a-zA-Z0-9的參數(shù)值
#wechat_redirect是無論直接打開還是做頁面302重定向時候,必須帶此參數(shù)
下圖為scope等于snsapi_userinfo時的授權頁面:
用戶同意授權后
如果用戶同意授權,頁面將跳轉至?
redirect_uri/?code=CODE&state=STATE。
若用戶禁止授權,則重定向后不會帶上code參數(shù),僅會帶上state參數(shù)redirect_uri?state=STATE
code說明?:?code作為換取access_token的票據(jù),每次用戶授權帶上的code將不一樣,code只能使用一次,5分鐘未被使用自動過期。
第二步:通過code換取網(wǎng)頁授權access_token
首先請注意,這里通過code換取的網(wǎng)頁授權access_token,與基礎支持中的access_token不同。公眾號可通過下述接口來獲取網(wǎng)頁授權access_token。如果網(wǎng)頁授權的作用域為snsapi_base,則本步驟中獲取到網(wǎng)頁授權access_token的同時,也獲取到了openid,snsapi_base式的網(wǎng)頁授權流程即到此為止。
請求方法獲取code后,請求以下鏈接獲取access_token:?
?https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數(shù)說明
參數(shù)是否必須說明
appid是公眾號的唯一標識
secret是公眾號的appsecret
code是填寫第一步獲取的code參數(shù)
grant_type是填寫為authorization_code
返回說明
正確時返回的JSON數(shù)據(jù)包如下:
{????"access_token":"ACCESS_TOKEN",????"expires_in":7200,????"refresh_token":"REFRESH_TOKEN",????"openid":"OPENID",????"scope":"SCOPE"?}
參數(shù)描述
access_token網(wǎng)頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
expires_inaccess_token接口調用憑證超時時間,單位(秒)
refresh_token用戶刷新access_token
openid用戶唯一標識,請注意,在未關注公眾號時,用戶訪問公眾號的網(wǎng)頁,也會產生一個用戶和公眾號唯一的OpenID
scope用戶授權的作用域,使用逗號(,)分隔
錯誤時微信會返回JSON數(shù)據(jù)包如下(示例為Code無效錯誤):
{"errcode":40029,"errmsg":"invalid?code"}
由于access_token擁有較短的有效期,當access_token超時后,可以使用refresh_token進行刷新,refresh_token擁有較長的有效期(7天、30天、60天、90天),當refresh_token失效的后,需要用戶重新授權。
請求方法
獲取第二步的refresh_token后,請求以下鏈接獲取access_token:??https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
參數(shù)是否必須說明
appid是公眾號的唯一標識
grant_type是填寫為refresh_token
refresh_token是填寫通過access_token獲取到的refresh_token參數(shù)
返回說明
正確時返回的JSON數(shù)據(jù)包如下:
{????"access_token":"ACCESS_TOKEN",????"expires_in":7200,????"refresh_token":"REFRESH_TOKEN",????"openid":"OPENID",????"scope":"SCOPE"?}
參數(shù)描述
access_token網(wǎng)頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
expires_inaccess_token接口調用憑證超時時間,單位(秒)
refresh_token用戶刷新access_token
openid用戶唯一標識
scope用戶授權的作用域,使用逗號(,)分隔
錯誤時微信會返回JSON數(shù)據(jù)包如下(示例為Code無效錯誤):
{"errcode":40029,"errmsg":"invalid?code"}
第四步:拉取用戶信息(需scope為 snsapi_userinfo)
如果網(wǎng)頁授權作用域為snsapi_userinfo,則此時開發(fā)者可以通過access_token和openid拉取用戶信息了。
請求方法
http:GET(請使用https協(xié)議)
?https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
參數(shù)說明
參數(shù)描述
access_token網(wǎng)頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
openid用戶的唯一標識
lang返回國家地區(qū)語言版本,zh_CN 簡體,zh_TW 繁體,en 英語
返回說明
正確時返回的JSON數(shù)據(jù)包如下:
{????"openid":"?OPENID",????"?nickname":?NICKNAME,????"sex":"1",????"province":"PROVINCE"????"city":"CITY",????"country":"COUNTRY",?????"headimgurl":????"http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",??"privilege":[?"PRIVILEGE1"?"PRIVILEGE2"?????]?}
參數(shù)描述
openid用戶的唯一標識
nickname用戶昵稱
sex用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知
province用戶個人資料填寫的省份
city普通用戶個人資料填寫的城市
country國家,如中國為CN
headimgurl用戶頭像,最后一個數(shù)值代表正方形頭像大小(有0、46、64、96、132數(shù)值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空
privilege用戶特權信息,json 數(shù)組,如微信沃卡用戶為(chinaunicom)
錯誤時微信會返回JSON數(shù)據(jù)包如下(示例為openid無效):
{"errcode":40003,"errmsg":"?invalid?openid?"}
請求方法
http:GET(請使用https協(xié)議)
?https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
參數(shù)說明
參數(shù)描述
access_token網(wǎng)頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
openid用戶的唯一標識
返回說明
正確的Json返回結果:
{?"errcode":0,"errmsg":"ok"}
錯誤時的Json返回示例:
{?"errcode":40003,"errmsg":"invalid?openid"}
案例代碼:
請求授權頁面的構造方式
url在線編碼工具:http://tool.oschina.net/encode?type=4
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
前端代碼
http://www.w3.org/TR/html4/strict.dtd";>http-equiv="Content-Type" content="text/html; charset=UTF-8" />會員注冊
function callback(result) {
alert('cucess');
alert(result);? //輸出openid
}
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
var code = getQueryString("code");
$.ajax({
async: false,?????? url: "http://atest.sinaapp.com/oauth2.php", //這是我的服務端處理文件php的
type: "GET",?????? //下面幾行是jsoup,如果去掉下面幾行的注釋,后端對應的返回結果也要去掉注釋
// dataType: 'jsonp',
// jsonp: 'callback', //jsonp的值自定義,如果使用jsoncallback,那么服務器端,要返回一個jsoncallback的值對應的對象.
// jsonpCallback:'callback',
data: {code:code}, //傳遞本頁面獲取的code到后臺,以便后臺獲取openid
timeout: 5000,
success: function (result) {
callback(result);
},
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus);?????? }
});
后端代碼
$code = $_GET['code'];//前端傳來的code值
$appid = "wx468622291a1e99d6";
$appsecret = "98566dc38863aa4395fabebb0de6ecc1";//獲取openid
$result = https_request($url);
$jsoninfo = json_decode($result, true);
$openid = $jsoninfo["openid"];//從返回json結果中讀出openid
$access_token = $jsoninfo["access_token"];//從返回json結果中讀出openid
$callback=$_GET['callback'];? // echo $callback."({result:'".$openid."'})";
$url1 = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openid&lang=zh_CN";
$result1 = https_request($url1);
$jsoninfo1 = json_decode($result1, true);
$nickname=$jsoninfo1["nickname"];
echo $openid.":".$access_token.":".$nickname; //把openid 送回前端
function https_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, 1);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
?>