微信開發三大坑:
1、微信OAuth2.0授權
2、微信jssdk簽名
3、微信支付簽名
本篇先搞定微信OAuth2.0授權吧!
實際一旦了解微信的OAuth2.0,其他的也掌握了。
以簡書的登陸頁面為例,來了解一下oauth2.0驗證授權的一些背景知識:
- 傳統的注冊登陸方式:
如果你是一個新用戶,則點擊新用戶注冊按鈕,進入由簡書提供的注冊頁面,進行用戶名密碼驗證和設置
然后再回到簡書提供的登陸頁面,輸入剛注冊的用戶名和密碼進行登陸
缺點(站在用戶的角度):
除非我很想使用該app,否則根本不想花這么多時間進行注冊,太麻煩了。
如果使用app很多,到處注冊,密碼要么一樣,要么多到你記不住
每次登陸還要手動輸入用戶名以及密碼,也是很麻煩的事情
優點(站在app提供者的角度):
- 對app提供者來說,新客戶注冊對其吸引投資,增加市值,加強影響力是有非常大的幫助。
那么有什么好的方法,能夠避免掉用戶注冊登陸的不便之處呢?
答案就是: 利用各個社交app(例如微信)現有的注冊賬號進行第三方(例如簡書)應用的驗證授權登陸,這就是傳說中的oauth2.0授權登陸。
之所以使用社交軟件賬號是因為用戶實在是夠多啊!作為國人,大家基本上都有微信,qq等賬號。這樣就只要點擊一下簡書登陸頁面中的社交賬號直接登陸中某個圖標就直接進入由社交app提供的授權頁面
- oauth2.0授權登陸:
上圖顯示了簡書使用微信/qq/豆瓣/新浪微博進行oauth2.0授權登陸的界面,該界面并不是由簡書提供的,而是由對應的各個社交app提供的
上面四個界面中,微信登陸只要按確認登陸就能登陸簡書app(不要注冊,不要填寫用戶名+密碼,只要點擊確認登陸就能登陸簡書。甚至可以通過靜默授權,連這個頁面都不需要顯示就直接進入簡書)。
其他的三個界面還是需要輸入對應社交app的用戶名+密碼。這是因為我只打開了微信app,qq沒開,至于豆瓣以及新浪微博,我還沒有賬號。
- 以簡書為例子,來簡單說明oauth2.0授權登陸流程:
什么是oatuh2.0協議:
OAuth2.0(開放授權)是一個開放標準。
沒啥好解釋的,就是一個標準允許第三方網站在用戶授權的前提下訪問在用戶在服務商那里存儲的各種信息。
蘊含很多信息哦!
這句話提到了三個角色:第三方網站/用戶/服務商
這句話是站在服務商的角度進行描述的。
服務商:以微信為例子,那么服務商就是微信[服務器]或騰訊
用戶 : 就是你,你的相關信息(例如用戶名/密碼/性別/ 省份等等等等)都是存放在服務商的服務器中。注意:你不是第三方(例如簡書)的用戶,而是微信的用戶(因為你是注冊在微信中,而不是簡書中)
第三方網站 : 這里指的就是簡書[服務器]而這種授權無需將用戶提供用戶名和密碼提供給該第三方網站。
這句話的意思很明顯,就是簡書服務器是沒法拿到你在微信服務器中的用戶名和密碼的,但是的確能夠讓你登陸簡書服務器既然第三方(簡書)無法拿到你的用戶名和密碼,那肯定是由服務商(微信)來進行驗證,那么第三方肯定要和服務商有一種機制來進行辨識:
在認證過程之前,第三方(簡書)需要先向服務商(微信)申請第三方(簡書)服務的唯一標識
因此第三方(簡書)填寫本公司相關信息,提供本公司賬號,域名等信息,并且花三百塊錢給服務商(騰訊)進行審核。服務商騰訊收到錢,并且審核通過后,會給第三方(簡書)兩個編號:AppID和appSecret(及其重要,不能泄露)。通過這兩個編號,就能確認唯一性了。當然過程是很復雜的。
-
第三方[服務器]和服務商[服務器]之間的通信:
既然第三方(簡書)用通過服務商(微信)來驗證用戶(你)身份的合法性,那么肯定涉及到:一旦服務商(微信)確認用戶(你)的合法身份后,如何將信息傳遞給第三方(簡書)
很簡單,通過第三方(簡書服務器)提供的回調URL,服務商(微信服務器)將相關數據以參數形式寫入到第三方(簡書服務器)提供的回調URL,第三方(簡書服務器)解析服務商(微信服務器)發過來的信息抽取出來就OK了!
那在微信公眾號的申請中,有要求第三方(簡書)提供回調地址
oauth2.0授權流程:
其中:
2--7步驟是通過簡書調用:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
這個API進行的,具體參數請參見文檔說明
8-9步驟是通過簡書調用:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
這個API進行的,具體參數請參見文檔說明
步驟10以后,是通過accesstoken以及openid等從微信獲取相關信息了
由于微信的開發需要審批,獨立的域名(不能使用localhost),并且要求是80端口(http)或443端口(https),這獨立域名以及這兩個端口需要工信部審批后才可使用,因此我這里目前沒有這種開發環境,但是我可以提供一段代碼,以前分享在群里面,用于進行微信oauth2.0授權,我以前可以獲取正確的結果,目前應該也可以。
只是例子而已,不要使用在生產環境:
由于使用nodejs的wechat-oauth庫進行微信oauth2.0授權操作
因此可以先npm install wechat-oauth --save下載到你的開發包中去
順便說一下,wechat-oauth是由深入淺出nodejs作者樸靈撰寫的庫
通過微信授權獲取openid和accesstoken示例代碼:
//1、引入wechat-oauth包
var OAuth = require('wechat-oauth');
//2、生成一個OAuth的實例,appId和appSecert作為構造參數
var oauthApi = new OAuth(你的appId, 你的appSecert);
//3、構造一個路由,用于獲取微信寫入到你的回調url中的code數據
//這個路由就是你注冊在微信開發中的回調url!!!!
//此時的你充當的是第三方網站角色,相當于簡書服務器
app.get('/callback', function (req, res) {
console.log('----weixin callback -----')
var code = req.query.code;
console.log("code =" + code);
//通過code獲取accesstoken
oauthApi.getAccessToken(code, function (err, result){
//如果函數調用成功,會在result中得到access_token
var accessToken = result.data.access_token;
//以及openid;
var openid = result.data.openid;
console.log('openid='+ openid);
//然后通過openid獲取用戶信息
oauthApi.getUser(openid, function (err, result1) {
console.log('use weixin api get user: ' + err)
console.log(result)
var oauth_user = result1;
//打印出用戶信息
console.log("userinfo" + JSON.stringify(oauth_user, null, ' '));
//授權成功獲取信息后,重定向到你要去的頁面
//這里隨便,所以直接重定向到首頁了,你可以換成其他任何頁面
res.redirect('/');
});
console.log("blf write" + JSON.stringify(result.data, null, ' '));
});
});
//url就是3、中定義的路由一致,用來接收微信發過來的code
//關鍵點: callbackURL必須要和3、中定義的路由一致!!!
// 且callbackURL就是你在微信中提供的回調url!!!
//就是上圖顯示的url!!!
var callbackURL = 'http://你的域名/callback';
//oauth2是你定義的路由,當你點擊微信登陸這個按鈕時,就調用oauth2這個路由,向騰訊請求oauth2授權驗證
//騰訊驗證通過,會將code寫入到3、這個回調url中
//然后通過3、路由,獲取code, 換取accesstoken以及openid
//再通過openid獲取userInfo,漂亮,完成整個操作
app.get('/oauth2', function(req, res) {
var url = oauthApi.getAuthorizeURL(callbackURL,'','snsapi_base');
console.log(url);
//重定向的回調地址,獲取code,通過code換取openid和accesstoken ,通過openid獲取用戶信息
//所有一起如此簡單
res.redirect(url);
})
用到了wechat-oauth庫中的三個api:
oauthApi.getAuthorizeURL
相當于2--7步驟是通過調用:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
還是貼一下該函數的源碼吧,這樣就清晰了
/**
* 獲取授權頁面的URL地址
* @param {String} redirect 授權后要跳轉的地址
* @param {String} state 開發者可提供的數據
* @param {String} scope 作用范圍,值為snsapi_userinfo和snsapi_base,前者用于彈出,后者用于跳轉
*/
OAuth.prototype.getAuthorizeURL = function (redirect, state, scope) {
var url = 'https://open.weixin.qq.com/connect/oauth2/authorize';
var info = {
appid: this.appid,
redirect_uri: redirect,
response_type: 'code',
scope: scope || 'snsapi_base',
state: state || ''
};
//合成授權請求url
//然后第三方網站(你)重定向到這個url中去
//其結果就是調用callback路由
//于是就運行你在callback中的代碼了
//流程銜接起來了
return url + '?' + querystring.stringify(info) + '#wechat_redirect';
};
oauthApi.getAccessToken
相當于8-9步驟是通過調用:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
OAuth.prototype.getAccessToken = function (code, callback) {
var url = 'https://api.weixin.qq.com/sns/oauth2/access_token';
var info = {
appid: this.appid,
secret: this.appsecret,
code: code,
grant_type: 'authorization_code'
};
var args = {
data: info,
dataType: 'json'
};
//請求url,通過code換取accesstoken,openid等等
this.request(url, args, wrapper(processToken(this, callback)));
};
oauthApi.getUser
相當于步驟10以后,是通過accesstoken以及openid等從微信獲取相關信息了
希望上面代碼對大家有幫助
- 下一步計劃:
由于微信的授權我這里沒有環境(其實國內的環境導致都需要獨立域名以及80/443端口問題),因此想實現一個類似騰訊的oauth2.0授權服務器。目前完成70%,還有一些問題需要解決。
[開發周記2017/3/26-2017/4/2]
(http://www.lxweimin.com/p/7417e20b74d6)
中有記錄,使用了node-oauth2-server庫開發oauth2.0服務器,但是登陸驗證的話,要使用passport,需要自己寫一個passport-strategy插件,這個有點麻煩。目前我需要向前推進,所以自己的oauth2.0授權和passport驗證放在以后實現(我覺得大概也不需要多久).
其實我的需求如下:
1、使用IBM loopback庫實現服務器
2、可以使用localhost:非80端口 進行oauth2.0授權回調,不需要獨立域名以及80/443端口
3、國內可以進行訪問,不需要那個啥(facebook/google可以使用localhost,并且非80/443端口,但是不那個啥就沒法訪問)
通過實驗,突然發現一個滿足上述所有要求的網站:
偉大的github,可以使用github開發賬戶,以localhost方式接受github發送過來的code,換取accesstoken等,進行oatuh2.0授權。
下一步我們就實戰,通過本地調用來實現github oauth2.0授權。
我們會使用loopback庫以及loopback-component-passport插件來演示一個Demo,大家會看到根本需要寫一句代碼,就能完美的進行oauth2.0授權!
IBM loopback非常好用,我會用loopback實現一個完整的服務器,與大家分享。
作為oauth2.0最后一部,我會使用node-oauth2-server以及passport實現自己的oauth2.0服務器,與大家分享實現的過程,以及node-oauth2-server(上個禮拜已經注釋好了)和passport(曾經讀過源碼,但是是去年,可能需要回憶一下,哈哈)的源碼分析
使用loopback-component-passport插件實現github和facebook登陸成功的圖片:
下一篇我們使用vue2.0來制作一個登陸頁面,并且了解服務端loopback的基礎知識