OAuth是一個(gè)開(kāi)放協(xié)議,允許用戶讓第三方應(yīng)用以安全且標(biāo)準(zhǔn)的方式獲取該用戶在某一網(wǎng)站上儲(chǔ)存的私密資源(如用戶個(gè)人資訊、照片、影片、聯(lián)絡(luò)人清單),而無(wú)須將使用者名稱和密碼提供給第三方應(yīng)用程式。本文將詳細(xì)介紹OAuth協(xié)定以及在微信裡的具體實(shí)作。
?
OAuth2.0協(xié)定介紹
OAuth2.0是OAuth協(xié)定的下一版本,但不向後相容OAuth 1.0。 OAuth 2.0關(guān)注客戶端開(kāi)發(fā)者的簡(jiǎn)易性,同時(shí)為Web應(yīng)用,桌面應(yīng)用和手機(jī),和起居室設(shè)備提供專門的認(rèn)證流程。 OAuth2.0允許使用者提供一個(gè)令牌,而不是使用者名稱和密碼來(lái)存取他們存放在特定服務(wù)提供者的資料。每一個(gè)令牌授權(quán)一個(gè)特定的網(wǎng)站(例如,影片編輯網(wǎng)站)在特定的時(shí)段(例如,接下來(lái)的2小時(shí)內(nèi))內(nèi)存取特定的資源(例如僅僅是某一相簿中的影片)。這樣,OAuth允許使用者授權(quán)第三方網(wǎng)站存取他們儲(chǔ)存在另外的服務(wù)提供者上的信息,而不需要分享他們的存取許可或他們資料的所有內(nèi)容。
?
OAuth2.0認(rèn)證和授權(quán)的具體流程:
在Oauth2.0認(rèn)證和授權(quán)的過(guò)程中涉及的三方包括:
#1 . 服務(wù)提供方,使用者使用服務(wù)提供者來(lái)儲(chǔ)存受保護(hù)的資源,如照片,視頻,聯(lián)絡(luò)人清單。
2. 用戶,存放在服務(wù)提供者的受保護(hù)的資源的擁有者。
3. 用戶端,要存取服務(wù)提供方資源的第三方應(yīng)用,通常是網(wǎng)站,如提供照片列印服務(wù)的網(wǎng)站。在認(rèn)證過(guò)程之前,客戶端要向服務(wù)提供者申請(qǐng)客戶端標(biāo)識(shí)。
?
使用OAuth進(jìn)行認(rèn)證與授權(quán)的流程如下所示:
#1. 使用者存取用戶端的網(wǎng)站,想操作使用者存放在服務(wù)提供者的資源;
2. 客戶端向服務(wù)提供者請(qǐng)求一個(gè)臨時(shí)令牌;
3. 服務(wù)提供者驗(yàn)證客戶端的身份後,授予一個(gè)臨時(shí)令牌;
#4.用戶端取得臨時(shí)令牌後,將使用者引導(dǎo)至服務(wù)提供者的授權(quán)頁(yè)面請(qǐng)求使用者授權(quán)。在這個(gè)過(guò)程中將臨時(shí)令牌和用戶端的回呼連線傳送給服務(wù)提供者;
5.?使用者在服務(wù)提供者的網(wǎng)頁(yè)上輸入使用者名稱和密碼,然後授權(quán)該客戶端存取所要求的資源;
6. 授權(quán)成功後,服務(wù)提供者引導(dǎo)使用者返回客戶端的網(wǎng)頁(yè);
#7.客戶端根據(jù)臨時(shí)令牌從服務(wù)提供者取得存取權(quán)杖;
8. 服務(wù)提供者根據(jù)臨時(shí)令牌和使用者的授權(quán)情況授予客戶端存取令牌;
9. 用戶端使用取得的存取權(quán)杖存取權(quán)存放在服務(wù)提供者上的受保護(hù)的資源。
微信網(wǎng)頁(yè)OAuth2.0授權(quán):
如果使用者在微信中(Web微信除外)造訪公眾號(hào)的第三方網(wǎng)頁(yè),公眾號(hào)開(kāi)發(fā)者可以透過(guò)此介面取得目前使用者基本資訊(包括暱稱、性別、城市、國(guó)家)。利用使用者資訊,可以實(shí)現(xiàn)體驗(yàn)最佳化、使用者來(lái)源統(tǒng)計(jì)、帳號(hào)綁定、使用者身分鑑權(quán)等功能。
要注意的是,獲取用戶基本資訊介面(稍後博文會(huì)介紹到)是在用戶和公眾號(hào)產(chǎn)生消息交互時(shí),才能根據(jù)用戶OpenID獲取用戶基本信息,而網(wǎng)頁(yè)授權(quán)的方式獲取用戶基本信息,則無(wú)需消息交互,只是用戶進(jìn)入到公眾號(hào)的網(wǎng)頁(yè),就可彈出請(qǐng)求用戶授權(quán)的界面,用戶授權(quán)後,就可獲得其基本信息(此過(guò)程甚至不需要用戶已經(jīng)關(guān)注公眾號(hào)。)
下面我們將透過(guò)一個(gè)具體的例子來(lái)展示開(kāi)發(fā)的詳細(xì)過(guò)程。
?
?
設(shè)定授權(quán)回呼網(wǎng)域:
?
在微信公眾號(hào)請(qǐng)求使用者網(wǎng)頁(yè)授權(quán)之前,開(kāi)發(fā)者需要先到公眾平臺(tái)網(wǎng)站的我的服務(wù)頁(yè)中配置授權(quán)回調(diào)名,要注意的是這裡的網(wǎng)域不要加http://或https://。另外,授權(quán)回呼域名配置規(guī)範(fàn)為全域名,例如需要網(wǎng)頁(yè)授權(quán)的域名為:www.qq.com,配置以後此域名下的所有頁(yè)面例如http://www.qq.com/music.html,?http: //www.qq.com/login.html都可以進(jìn)行OAuth2.0鑑權(quán)。但http://pay.qq.com,?http://music.qq.com無(wú)法進(jìn)行OAuth2.0鑑權(quán)。
為此進(jìn)入到服務(wù)頁(yè)(使用正式的服務(wù)號(hào)碼或認(rèn)證後的訂閱號(hào)碼後透過(guò)我的服務(wù)找到,如果是測(cè)試帳號(hào)直接在首頁(yè)即可找到)後找到OAuth2.0網(wǎng)頁(yè)授權(quán),點(diǎn)擊右側(cè)的修改連結(jié):
在彈出視窗輸入網(wǎng)域後點(diǎn)擊確定按鈕儲(chǔ)存:
此步驟相當(dāng)於前面介紹到的OAuth2.0認(rèn)證過(guò)程的第二步“客戶端向服務(wù)提供者請(qǐng)求一個(gè)臨時(shí)令牌”,這裡的Code即是臨時(shí)令牌,為此可以請(qǐng)求微信的OAuth2 .0介面以取得該Code,該介面的參數(shù)需要指定一個(gè)回呼頁(yè)面URL,為此我們需要建立一個(gè)Apex Page,為此登陸Force.com後找到域名,通常從中國(guó)訪問(wèn)的域名是https:// ap1.salesforce.com, 在瀏覽器網(wǎng)址列輸入https://ap1.salesforce.com/apex/oauth2test, 此時(shí)Force.com將提示頁(yè)不存在,點(diǎn)選「Create Page oauth2test」連結(jié)建立頁(yè)面:
?
創(chuàng)建好後的頁(yè)面如下,如果啟用了開(kāi)發(fā)者模式,則頁(yè)面分為上下兩個(gè)部分,上部分是顯示效果,下面是源代碼編輯窗口,默認(rèn)Force.com會(huì)將自身的頂部導(dǎo)航、左側(cè)導(dǎo)航以及CSS樣式應(yīng)用到新建立的頁(yè)面:
我們透過(guò)在第一行加入以下程式碼告訴Force .com不要使用預(yù)設(shè)的CSS樣式,不要顯示頂部以及左側(cè)的導(dǎo)覽欄,同時(shí)最後一個(gè)controller屬性指定了apex頁(yè)面對(duì)應(yīng)的控制器類,類似於aspx頁(yè)面對(duì)應(yīng)的aspx.cs類,滑鼠保持在編輯欄視窗,按住Ctrl + S組合鍵即可儲(chǔ)存編輯後的程式碼:
?
此時(shí),對(duì)應(yīng)的oauth2testcontroller類別並不存在,瀏覽器會(huì)報(bào)以下錯(cuò)誤:
這裡點(diǎn)選第二個(gè)連結(jié)「Create Apex class 'public class oauth2testcontroller'」自動(dòng)建立控制器類別。留意這兩個(gè)連結(jié)的唯一區(qū)別在於」with sharing」關(guān)鍵字,這個(gè)關(guān)鍵字指定了當(dāng)前類別對(duì)各個(gè)對(duì)物件(相當(dāng)於資料表)、欄位等的存取權(quán)限與目前登入使用者同,如果不指定,Apex頁(yè)面將擁有對(duì)所有物件、欄位的存取權(quán)限。創(chuàng)建好後在下方程式碼編輯欄中將多出一個(gè)控制器類別Tab:
#在該類別中加入程式碼如下:
public class oauth2testcontroller { public String code {get; set;} public oauth2testcontroller(){ code = ApexPages.currentPage().getParameters().get('code'); if(String.isBlank(code)){ code = 'No Code'; } } }
?
這段程式碼中第2行定義了一個(gè)公開(kāi)屬性code,第4行透過(guò)ApexPages物件取得URL中的code參數(shù),接著判斷是否code值是否為空,如果為空則提示No Code。下面我們會(huì)看到微信授權(quán)成功回呼此URL時(shí)會(huì)將code參數(shù)加入U(xiǎn)RL。
接下來(lái)稍微修改前臺(tái)頁(yè)面,在頁(yè)面中顯示得到的code值:
<apex:page standardstylesheets="false" showHeader="false" sidebar="false" controller="oauth2testcontroller"> {!code} </apex:page>
{!物件名稱}是Force.com Visualforce page裡用來(lái)顯示物件值的語(yǔ)法,接下來(lái)我們需要配置該頁(yè)面能夠透過(guò)公網(wǎng)進(jìn)行訪問(wèn),為此登陸Force.com後,進(jìn)入Setup –> Develop –> Sites,點(diǎn)擊網(wǎng)站對(duì)應(yīng)的Site Label標(biāo)籤如下圖:
#進(jìn)入詳細(xì)設(shè)定頁(yè)面後找到“Site Visualforce Page”,點(diǎn)擊右側(cè)的Edit按鈕:
找到左側(cè)清單中的oauth2test頁(yè)面添加到右側(cè),並儲(chǔ)存修改:
此時(shí)即可透過(guò)http://johnson0001-developer-edition.ap1.force.com/oauth2test公網(wǎng)位址來(lái)訪問(wèn)前面創(chuàng)造的頁(yè)面了。接下來(lái)我們可以利用微信平臺(tái)的OAuth2認(rèn)證介面組拼URL並引導(dǎo)用戶透過(guò)微信來(lái)訪問(wèn),該介面的格式如下:
https://open.weixin.qq.com/connect/oauth2/ authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“該鏈接無(wú)法訪問(wèn)”,請(qǐng)檢查參數(shù)是否填寫錯(cuò)誤,是否擁有scope參數(shù)對(duì)應(yīng)的授權(quán)作用域權(quán)限,其中每個(gè)參數(shù)的詳細(xì)說(shuō)明如下:
在我們的例子里URL如下,其中scope我們指定為snsapi_userinfo,彈出授權(quán)頁(yè)面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx3b3aef2c09447269&redirect_uri=http://johnson0001-developer-edition.ap1.force.com/oauth2test&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
興許是測(cè)試賬號(hào)的關(guān)系,雖然微信接口文檔里提到在制定scope為snsapi_userinfo的情況下會(huì)彈出如下圖左所示的授權(quán)頁(yè)面,但反復(fù)嘗試(乃至刪除并重新關(guān)注賬號(hào))中也沒(méi)有看到該頁(yè)面,不過(guò)重點(diǎn)是我們得到了臨時(shí)令牌,如下圖右所示。右圖實(shí)際是http://johnson0001-developer-edition.ap1.force.com/oauth2test頁(yè)面,用戶同意授權(quán)后跳轉(zhuǎn)到(或者我遇到的實(shí)際情況是直接跳轉(zhuǎn))到redirect_uri/?CODE&state=STATE。若用戶禁止授權(quán),則重定向后不會(huì)帶上code參數(shù),僅會(huì)帶上state參數(shù)redirect_uri?state=STATE。
另外特別需要說(shuō)明的是,code作為換取access_token的臨時(shí)票據(jù),每次用戶授權(quán)帶上的code都不一樣,code只能使用一次,5分鐘未被使用自動(dòng)過(guò)期。
通過(guò)Code換取網(wǎng)頁(yè)授權(quán)access_token:
首先請(qǐng)注意,這里通過(guò)code換取的網(wǎng)頁(yè)授權(quán)access_token,與基礎(chǔ)支持中的access_token不同。公眾號(hào)可通過(guò)下述接口來(lái)獲取網(wǎng)頁(yè)授權(quán)access_token。如果網(wǎng)頁(yè)授權(quán)的作用域?yàn)閟nsapi_base,則本步驟中獲取到網(wǎng)頁(yè)授權(quán)access_token的同時(shí),也獲取到了 openid,snsapi_base式的網(wǎng)頁(yè)授權(quán)流程即到此為止。 獲取code后,可以通過(guò)以下接口獲取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
這里的CODE即為通過(guò)前面方式獲得的臨時(shí)令牌(票據(jù)),參數(shù)的具體說(shuō)明如下:
將URL直接輸入到瀏覽器地址欄即可得到返回?cái)?shù)據(jù),當(dāng)然真實(shí)場(chǎng)景里更多通過(guò)后臺(tái)代碼來(lái)請(qǐng)求,正確返回時(shí)的JSON數(shù)據(jù)包如下:
{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" }
參數(shù)的具體說(shuō)明如下:
錯(cuò)誤時(shí)微信會(huì)返回JSON數(shù)據(jù)包如下(示例為Code無(wú)效錯(cuò)誤):
{"errcode":40029,"errmsg":"invalid code"}
在本例中獲得的access_token實(shí)例如下:
{"access_token":"OezXcEiiBSKSxW0eoylIeMEUA_AZuBDY8AO0IIw270MMsvemqLvgx1HqemeXIZfzXW2d6yHCPy9cA1yHZ1jHCkwlH5Ct5Jfa1jOQm88M9LzU_O8BCKMNhN7yLlHJfOFLuf4lLTNGOOsoWYxQzYVNGw","expires_in":7200,"refresh_token":"OezXcEiiBSKSxW0eoylIeMEUA_AZuBDY8AO0IIw270MMsvemqLvgx1HqemeXIZfz_Vj5pJZlv2V5wK9EzWmxQmM07cqIAwMXOdqzlQs-NY4hiyENP4WhO4Twpko-3iY_pAPZRnGGmAVt3DirZaWIyg","openid":"ou-37t936RNZEcW0mI75RN2pdxkc","scope":"snsapi_userinfo"}
可以看到上面access_token的默認(rèn)失效時(shí)間是7200秒,也就是2小時(shí),當(dāng)access_token超時(shí)后,可以通過(guò)refresh_token進(jìn)行刷新,refresh_token擁有較長(zhǎng)的有效期(7天、30天、60天、90天),當(dāng)refresh_token失效后,需要用戶重新授權(quán),簡(jiǎn)化理解起見(jiàn),我們?cè)诒疚牡淖詈笤俳榻B相關(guān)技術(shù)。
拉取用戶信息(需Scope為snasapi_userinfo):
通過(guò)access_token獲取用戶信息的接口如下,使用GET方法:
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
參數(shù)具體說(shuō)明如下:
本例的URL如下:
https://api.weixin.qq.com/sns/userinfo?access_token=OezXcEiiBSKSxW0eoylIeMEUA_AZuBDY8AO0IIw270MMsvemqLvgx1HqemeXIZfzXW2d6yHCPy9cA1yHZ1jHCkwlH5Ct5Jfa1jOQm88M9LzU_O8BCKMNhN7yLlHJfOFLuf4lLTNGOOsoWYxQzYVNGw&openid=ou-37t936RNZEcW0mI75RN2pdxkc&lang=zh_CN
輸入瀏覽器訪問(wèn)即可得到相應(yīng)的用戶信息:
{"openid":"ou-37t936RNZEcW0mI75RN2pdxkc","nickname":"王浩","sex":1,"language":"zh_CN","city":"松江","province":"上海","country":"中國(guó)","headimgurl":"http:\/\/wx.qlogo.cn\/mmopen\/lqsZNvDqcXe8nBKHBPsp9YHuZXPtkzOD1uq3r3xxDicuDLKGlicNd1b371ODnn9xNBB9y9ChBSfL7tuX6m9FS8koY9Ex1iaJRDI\/0","privilege":[]}
刷新access_token:
可以通過(guò)前面在“通過(guò)Code換取網(wǎng)頁(yè)授權(quán)access_token”小節(jié)中獲得的refresh_token來(lái)調(diào)用刷新Token接口獲取更新的access_token,微信在API文檔里介紹refresh_token擁有較長(zhǎng)的有效期(7天、30天、60天、90天),但實(shí)際微信的refresh_token的有效期是多長(zhǎng)沒(méi)有具體說(shuō)明,如果有具體經(jīng)驗(yàn)的朋友歡迎分享。微信刷新access_token的接口如下:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
接口的具體參數(shù)定義如下:
正確時(shí)返回的JSON數(shù)據(jù)包如下:
{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" }
數(shù)據(jù)包的具體定義如下:
錯(cuò)誤時(shí)微信會(huì)返回JSON數(shù)據(jù)包如下(示例為Code無(wú)效錯(cuò)誤):
{"errcode":40029,"errmsg":"invalid code"}
更多Force.com微信開(kāi)發(fā)系列OAuth2.0網(wǎng)頁(yè)授權(quán)相關(guān)文章請(qǐng)關(guān)注PHP中文網(wǎng)!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6
視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版
神級(jí)程式碼編輯軟體(SublimeText3)
