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

Video Face Swap
使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱門文章

熱工具

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

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

禪工作室 13.0.1
功能強(qiáng)大的PHP集成開發(fā)環(huán)境

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

SublimeText3 Mac版
神級(jí)代碼編輯軟件(SublimeText3)