菜菜君,我又來啦
又有什么事嗎?
我按照你上篇文章寫的JWT的方式已經(jīng)把網(wǎng)站認證寫完了,而且效果還不錯
那恭喜你呀,下次面試又多了一項技能
不過,現(xiàn)在又有一個問題,我做的系統(tǒng)有一個合作商想要利用我們的用戶信息登錄他們的系統(tǒng)
你還要做授權(quán)呀?
是呀,我的思路是讓用戶在第三方系統(tǒng)的輸入賬號密碼,然后第三方的服務(wù)端請求我們服務(wù)器來驗證正確性
這樣做真的好嗎?
這樣做我們的系統(tǒng)改動很小呀,我覺得很好呀
這樣做有很多弊端呀,且聽我給你講個小故事
以下業(yè)務(wù)場景只針對于Web系統(tǒng),而且Web頁面有后臺服務(wù)程序的場景。
開端
那一年,我所在公司的用戶量達到了公司成立以來的新高峰,經(jīng)過多個程序員日日夜夜加班,每個業(yè)務(wù)系統(tǒng)達到了幾乎四個9的穩(wěn)定性,同時業(yè)務(wù)在業(yè)界也有了一定的知名度。那一天突然有一個合作商登門拜訪,提出合作共贏的意向。業(yè)務(wù)的場景就是我們的系統(tǒng)用戶能夠在他們系統(tǒng)登錄,并能夠獲取用戶一定的信息以便進行一些業(yè)務(wù)操作。
他們希望我們能夠把已存在的用戶數(shù)據(jù)Copy一份導(dǎo)入他們的系統(tǒng),并且新注冊的用戶進行單項同步更新。這不是蝦扯蛋嗎?.....
為什么不可行
為了實現(xiàn)用戶信息互通而達到業(yè)務(wù)要求,其實方案有很多。如果不是底線情況下,同步用戶信息這種方案就是一個外行人,一個扯淡的方案。為什么這么說?首先說信息同步這種方式,如果是單項同步,雙方所有相關(guān)人員的工作量已經(jīng)非常之大,一定條件下單項同步升級為雙向信息同步,雙方的編程人員將會苦不堪言。
另外撇開工作量,用戶的信息本質(zhì)上屬于用戶的私密信息,一個用戶能夠把自己的隱私放心的存儲在你這里,就說明了對公司的信任度。一旦發(fā)生用戶信息復(fù)制的操作,本質(zhì)上是對用戶的不負責(zé)任,道德上,法律上都有所欠缺。
解決方案
作為一個技術(shù)人員,排除不合理方案,提供在業(yè)務(wù)可行情況下的技術(shù)方案是職責(zé)所在,那有沒有不用復(fù)制用戶信息這么low
B的方案呢?假設(shè)我們所在公司的系統(tǒng)為A,業(yè)務(wù)的域名為www.A.com,第三方系統(tǒng)為B,業(yè)務(wù)域名為www.B.com
記住我們的最終業(yè)務(wù)目標:允許我們公司的用戶(A系統(tǒng))在第三方系統(tǒng)(B系統(tǒng))能夠登錄,并且能夠獲取用戶一些相關(guān)的信息。極限業(yè)務(wù)情況下,在A系統(tǒng)用戶修改了相關(guān)信息,并且同步到B系統(tǒng)。
解決方案1
在第三方系統(tǒng)登錄的入口,允許我方用戶輸入賬號密碼,然后第三方系統(tǒng)(客戶端或者服務(wù)端都可以)攜帶用戶輸入的賬號密碼請求我司登錄服務(wù)器,如果驗證通過則返回用戶相關(guān)信息,第三方系統(tǒng)接收到返回數(shù)據(jù),按照自己相關(guān)的登錄流程進行登錄,并且可以存儲用戶相關(guān)的信息。請求的形式和大體的流程如下圖所示
http://www.A.com/login?loginname=caicai&pwd=buzhidao
說實話,我并不推薦這種方案,雖然它比直接復(fù)制用戶信息要好一些,但是依然問題很大,用戶在無形中已經(jīng)把賬號密碼或者其他登錄憑證泄露給并不信任的第三方系統(tǒng)中,而這可能并非用戶想要的結(jié)果。
解決方案2
以上方案有一個致命的缺點,那就是登錄頁面是用戶并不信任的第三方頁面,如果能避免這樣的危險,讓用戶在信任的我方登錄,會大大增強用戶的信任度。技術(shù)方面在我方實現(xiàn)登錄實在是容易,唯一需要考慮的是用戶登錄成功之后如何把用戶信息發(fā)送給第三方系統(tǒng)。如果采用請求調(diào)用的方式(比如:登錄成功,我方調(diào)用第三方一個接口),技術(shù)上可以實現(xiàn),但是下次再來一個第三方申請這樣的業(yè)務(wù),我方的調(diào)用接口可能會需要修改,所以現(xiàn)在業(yè)界比較好的也比較通用的方式是通過地址的跳轉(zhuǎn)來實現(xiàn)。具體流程如下:
1. 用戶在第三方點擊登錄,跳轉(zhuǎn)到我方提供的登錄頁面,頁面URL中帶有登錄成功跳轉(zhuǎn)的頁面地址,并在此頁面輸入賬號密碼。
2. 我方根據(jù)用戶賬號密碼判斷用戶正確性,登陸成功,獲取用戶信息。
3. 然后跳轉(zhuǎn)到第三方提供的登錄成功跳轉(zhuǎn)頁面,并把用戶信息攜帶過去。
4. 第三方跳轉(zhuǎn)頁面接收到用戶信息,處理剩余業(yè)務(wù),流程結(jié)束。
第一步中第三方跳轉(zhuǎn)到我方的登錄頁面URL如下所示:
http://www.A.com/login?type=userinfo&redirecturi=http://www.B.com/callback
解決方案3
方案2中登錄部分已經(jīng)和方案1有了本質(zhì)的區(qū)別,雖然僅僅是一個登錄方的改變,安全性以及對用戶隱私的保護上卻有著大大的提升。但是流程中卻依然存在著主動傳輸用戶信息,如果有人劫持的話,還是有用戶信息泄露的風(fēng)險。如何避免這樣的風(fēng)險呢?
試想,能否利用其它憑據(jù)來代替用戶信息呢?當然是可以,這也是現(xiàn)代Web系統(tǒng)實現(xiàn)授權(quán)的普遍方式。用戶信息取而代之的是一個令牌,而且這個令牌有一定的時效性,只能維持一段時間內(nèi)有效,這在一定程度上保護了系統(tǒng)數(shù)據(jù)。第三方系統(tǒng)獲取到這個令牌之后,每次獲取用戶信息都會攜帶者這個令牌作為憑證,我方的系統(tǒng)同時也只認可這個令牌作為授權(quán)的憑證。
http://www.A.com/login?type=token&redirecturi=http://www.B.com/callback
這里我要順便說一下,令牌的下發(fā)是通過前端(瀏覽器)的跳轉(zhuǎn)傳輸給第三方系統(tǒng),然后第三方系統(tǒng)的前端傳輸給后端,然后第三方的后端攜帶令牌獲取用戶信息,要注意哦,如果是第三方前端頁面攜帶令牌去獲取用戶信息,毫無安全性而言。
方案4
方案3其實在很多時候已經(jīng)足夠了,但是有一點需要注意,每個令牌有一定的有效時間,這是設(shè)計上的優(yōu)勢,同時也意味著令牌如果被其他人獲取到,一樣可以竊取用戶信息,由于在方案3中令牌的下發(fā)實際上還是通過前端(瀏覽器)來傳輸?shù)?,凡是在前端傳輸?shù)那闆r下,就會有泄露的風(fēng)險,那有沒有辦法避免在前端傳輸呢?
這里需要提醒一點,要想實現(xiàn)我方用戶可以登錄第三方系統(tǒng),并且在保護用戶隱私的情況下,在我方登錄是必須的。而且我方系統(tǒng)必須頒發(fā)給第三方系統(tǒng)一個憑證才能達到第三方獲取我方用戶的要求。
既然傳輸憑證不可避免,于是人們便想到了可以在前端(瀏覽器)傳輸一個只有一次有效的憑證,然后第三方后端依據(jù)這個憑證去獲取令牌,因為服務(wù)端的通信要比前端(瀏覽器)的通信要安全的多。于是方案4應(yīng)運而生:
1. 用戶跳轉(zhuǎn)到我方登錄頁面進行登錄。
2. 我方驗證用戶用戶名密碼無誤,產(chǎn)生一個有效次數(shù)為1并且一定時間內(nèi)有效的code,并攜帶著這個code跳轉(zhuǎn)到第三方的回調(diào)頁面
3. 第三方回調(diào)頁面,收到code參數(shù),傳輸給后端程序。
4. 第三方后端程序收到code參數(shù),攜帶著code調(diào)用我方接口
5. 我方驗證code有效性,如果有效則返回令牌信息
6. 第三方收到令牌信息,攜帶令牌信息調(diào)用我方接口獲取用戶信息
7. 我方驗證token有效性,如果有效則返回用戶信息
8. 之后的每次調(diào)用都攜帶者token進行訪問,code就算被人獲取到已經(jīng)不起作用
http://www.A.com/login?type=code&redirecturi=http://www.B.com/callback
升級
方案4雖然看上去已經(jīng)足夠好,但是并非完美。
1.?
當?shù)谌教D(zhuǎn)到我方登錄頁面的時候,我方并不知道這個第三方是誰,是不是可信任的,所以有必要讓我方識別這個第三方是否可以信任。我方在授權(quán)第三方的時候可以給每一個第三方頒發(fā)一個類似于appid和appkey的數(shù)據(jù),appid用來標識每一個我方授權(quán)的第三方,而且每一個appid必須注冊進行回調(diào)的url。這樣當?shù)谌教D(zhuǎn)到我方登錄頁面的時候,我方就可以識別出來這個第三方以及回調(diào)跳轉(zhuǎn)的url是否有效。
2.
當?shù)谌綌y帶者code去換取token,以及之后攜帶token去獲取用戶信息的每次通信,都應(yīng)該按照我方規(guī)則利用appid和appkey進行簽名處理,這樣我方的服務(wù)器端也能夠識別出來調(diào)用方是否是可信任的。
3. 在用戶登錄授權(quán)的頁面,用戶可勾選自己授權(quán)給第三方的數(shù)據(jù)內(nèi)容,這些權(quán)限將作用于code以及令牌中。
4. 由于每個令牌都有失效時間,如何更新令牌則會是一個技術(shù)點,其實完全可以在下發(fā)令牌的同時也下發(fā)一個用于更新令牌的令牌,這個令牌隨著每次重新下發(fā)令牌而更新。
5. 我方用戶的信息每次更新的時候,可以把相關(guān)的令牌失效,以達到讓第三方重新獲取用戶信息而同步的效果
6. 我方登錄頁面以及供第三方調(diào)用的所有接口都應(yīng)該采用https協(xié)議,并要求所有的第三方回調(diào)頁面必須也全部采用https,這能有效的仿制惡性劫持。
不知道菜菜把不清楚author2.0 授權(quán)的同學(xué)教會了沒有,如果還不清楚,請私信菜菜?
熱門工具 換一換