程序員過關斬將--要想獲取個人用戶信息,就得按照規矩來

菜菜君,我又來啦php

又有什麼事嗎?前端

我按照你上篇文章寫的JWT的方式已經把網站認證寫完了,並且效果還不錯程序員

那恭喜你呀,下次面試又多了一項技能web

不過,如今又有一個問題,我作的系統有一個合做商想要利用咱們的用戶信息登陸他們的系統面試

你還要作受權呀?編程

是呀,個人思路是讓用戶在第三方系統的輸入帳號密碼,而後第三方的服務端請求咱們服務器來驗證正確性後端

這樣作真的好嗎?瀏覽器

這樣作咱們的系統改動很小呀,我以爲很好呀安全

這樣作有不少弊端呀,且聽我給你講個小故事服務器

如下業務場景只針對於Web系統,並且Web頁面有後臺服務程序的場景。


開端

那一年,我所在公司的用戶量達到了公司成立以來的新高峯,通過多個程序員日日夜夜加班,每一個業務系統達到了幾乎四個9的穩定性,同時業務在業界也有了必定的知名度。那一天忽然有一個合做商登門拜訪,提出合做雙贏的意向。業務的場景就是咱們的系統用戶可以在他們系統登陸,並可以獲取用戶必定的信息以便進行一些業務操做。


他們但願咱們可以把已存在的用戶數據Copy一份導入他們的系統,而且新註冊的用戶進行單項同步更新。這不是蝦扯蛋嗎?.....

爲何不可行

爲了實現用戶信息互通而達到業務要求,其實方案有不少。若是不是底線狀況下,同步用戶信息這種方案就是一個外行人,一個扯淡的方案。爲何這麼說?首先說信息同步這種方式,若是是單項同步,雙方全部相關人員的工做量已經很是之大,必定條件下單項同步升級爲雙向信息同步,雙方的編程人員將會苦不堪言。


另外撇開工做量,用戶的信息本質上屬於用戶的私密信息,一個用戶可以把本身的隱私放心的存儲在你這裏,就說明了對公司的信任度。一旦發生用戶信息複製的操做,本質上是對用戶的不負責任,道德上,法律上都有所欠缺。

解決方案

做爲一個技術人員,排除不合理方案,提供在業務可行狀況下的技術方案是職責所在,那有沒有不用複製用戶信息這麼low B的方案呢?假設咱們所在公司的系統爲A,業務的域名爲www.A.com,第三方系統爲B,業務域名爲www.B.com

記住咱們的最終業務目標:容許咱們公司的用戶(A系統)在第三方系統(B系統)可以登陸,而且可以獲取用戶一些相關的信息。極限業務狀況下,在A系統用戶修改了相關信息,而且同步到B系統。

解決方案1

在第三方系統登陸的入口,容許我方用戶輸入帳號密碼,而後第三方系統(客戶端或者服務端均可以)攜帶用戶輸入的帳號密碼請求我司登陸服務器,若是驗證經過則返回用戶相關信息,第三方系統接收到返回數據,按照本身相關的登陸流程進行登陸,而且能夠存儲用戶相關的信息。請求的形式和大致的流程以下圖所示

http://www.A.com/login?loginname=caicai&pwd=buzhidao

說實話,我並不推薦這種方案,雖然它比直接複製用戶信息要好一些,可是依然問題很大,用戶在無形中已經把帳號密碼或者其餘登陸憑證泄露給並不信任的第三方系統中,而這可能並不是用戶想要的結果。

解決方案2

以上方案有一個致命的缺點,那就是登陸頁面是用戶並不信任的第三方頁面,若是能避免這樣的危險,讓用戶在信任的我方登陸,會大大加強用戶的信任度。技術方面在我方實現登陸實在是容易,惟一須要考慮的是用戶登陸成功以後如何把用戶信息發送給第三方系統。若是採用請求調用的方式(好比:登陸成功,我方調用第三方一個接口),技術上能夠實現,可是下次再來一個第三方申請這樣的業務,我方的調用接口可能會須要修改,因此如今業界比較好的也比較通用的方式是經過地址的跳轉來實現。具體流程以下:

1. 用戶在第三方點擊登陸,跳轉到我方提供的登陸頁面,頁面URL中帶有登陸成功跳轉的頁面地址,並在此頁面輸入帳號密碼。

2. 我方根據用戶帳號密碼判斷用戶正確性,登錄成功,獲取用戶信息。

3. 而後跳轉到第三方提供的登陸成功跳轉頁面,並把用戶信息攜帶過去。

4. 第三方跳轉頁面接收到用戶信息,處理剩餘業務,流程結束。

第一步中第三方跳轉到我方的登陸頁面URL以下所示:

http://www.A.com/login?type=userinfo&redirecturi=http://www.B.com/callback

解決方案3

方案2中登陸部分已經和方案1有了本質的區別,雖然僅僅是一個登陸方的改變,安全性以及對用戶隱私的保護上卻有着大大的提高。可是流程中卻依然存在着主動傳輸用戶信息,若是有人劫持的話,仍是有用戶信息泄露的風險。如何避免這樣的風險呢?


試想,可否利用其它憑據來代替用戶信息呢?固然是能夠,這也是現代Web系統實現受權的廣泛方式。用戶信息取而代之的是一個令牌,並且這個令牌有必定的時效性,只能維持一段時間內有效,這在必定程度上保護了系統數據。第三方系統獲取到這個令牌以後,每次獲取用戶信息都會攜帶者這個令牌做爲憑證,我方的系統同時也只承認這個令牌做爲受權的憑證。

http://www.A.com/login?type=token&redirecturi=http://www.B.com/callback


這裏我要順便說一下,令牌的下發是經過前端(瀏覽器)的跳轉傳輸給第三方系統,而後第三方系統的前端傳輸給後端,而後第三方的後端攜帶令牌獲取用戶信息,要注意哦,若是是第三方前端頁面攜帶令牌去獲取用戶信息,毫無安全性而言。

方案4

方案3其實在不少時候已經足夠了,可是有一點須要注意,每一個令牌有必定的有效時間,這是設計上的優點,同時也意味着令牌若是被其餘人獲取到,同樣能夠竊取用戶信息,因爲在方案3中令牌的下發實際上仍是經過前端(瀏覽器)來傳輸的,凡是在前端傳輸的狀況下,就會有泄露的風險,那有沒有辦法避免在前端傳輸呢?

這裏須要提醒一點,要想實現我方用戶能夠登陸第三方系統,而且在保護用戶隱私的狀況下,在我方登陸是必須的。並且我方系統必須頒發給第三方系統一個憑證才能達到第三方獲取我方用戶的要求。

既然傳輸憑證不可避免,因而人們便想到了能夠在前端(瀏覽器)傳輸一個只有一次有效的憑證,而後第三方後端依據這個憑證去獲取令牌,由於服務端的通訊要比前端(瀏覽器)的通訊要安全的多。因而方案4應運而生:

1. 用戶跳轉到我方登陸頁面進行登陸。

2. 我方驗證用戶用戶名密碼無誤,產生一個有效次數爲1而且必定時間內有效的code,並攜帶着這個code跳轉到第三方的回調頁面

3. 第三方回調頁面,收到code參數,傳輸給後端程序。

4. 第三方後端程序收到code參數,攜帶着code調用我方接口

5. 我方驗證code有效性,若是有效則返回令牌信息

6. 第三方收到令牌信息,攜帶令牌信息調用我方接口獲取用戶信息

7. 我方驗證token有效性,若是有效則返回用戶信息

8. 以後的每次調用都攜帶者token進行訪問,code就算被人獲取到已經不起做用

http://www.A.com/login?type=code&redirecturi=http://www.B.com/callback

升級

方案4雖然看上去已經足夠好,可是並不是完美。

1. 當第三方跳轉到我方登陸頁面的時候,我方並不知道這個第三方是誰,是否是可信任的,因此有必要讓我方識別這個第三方是否能夠信任。我方在受權第三方的時候能夠給每個第三方頒發一個相似於appid和appkey的數據,appid用來標識每個我方受權的第三方,並且每個appid必須註冊進行回調的url。這樣當第三方跳轉到我方登陸頁面的時候,我方就能夠識別出來這個第三方以及回調跳轉的url是否有效。

2. 當第三方攜帶者code去換取token,以及以後攜帶token去獲取用戶信息的每次通訊,都應該按照我方規則利用appid和appkey進行簽名處理,這樣我方的服務器端也可以識別出來調用方是不是可信任的。

3. 在用戶登陸受權的頁面,用戶可勾選本身受權給第三方的數據內容,這些權限將做用於code以及令牌中。

4. 因爲每一個令牌都有失效時間,如何更新令牌則會是一個技術點,其實徹底能夠在下發令牌的同時也下發一個用於更新令牌的令牌,這個令牌隨着每次從新下發令牌而更新。

5. 我方用戶的信息每次更新的時候,能夠把相關的令牌失效,以達到讓第三方從新獲取用戶信息而同步的效果

6. 我方登陸頁面以及供第三方調用的全部接口都應該採用https協議,並要求全部的第三方回調頁面必須也所有采用https,這能有效的仿製惡性劫持。

不知道菜菜把不清楚author2.0 受權的同窗教會了沒有,若是還不清楚,請私信菜菜 

相關文章
相關標籤/搜索