利用快取實現APP端與伺服器介面互動的Session統制

hwk_yellow發表於2016-11-16

與傳統B/S模式的Web系統不同,移動端APP與伺服器之間的介面互動一般是C/S模式,這種情況下如果涉及到使用者登入的話,就不能像Web系統那樣依賴於Web容器來管理Session了,因為APP每發一次請求都會在伺服器端建立一個新的Session。而有些涉及到使用者隱私或者資金交易的介面又必須確認當前使用者登入的合法性,如果沒有登入或者登入已過期則不能進行此類操作。 
我見過一種“偷懶”的方式,就是在使用者第一次登入之後,儲存使用者的ID在本地儲存中,之後跟伺服器互動的介面都通過使用者ID來標識使用者身份。

這種方式主要有兩個弊端:

只要本地儲存的使用者ID沒有被刪掉,就始終可以訪問以上介面,不需要重新登入,除非增加有效期的判斷或者使用者主動退出;
介面安全性弱,因為使用者ID對應了資料庫裡的使用者唯一標識,別人只要能拿到使用者ID或者偽造一個使用者ID就可以使用以上介面對該使用者進行非法操作。


使用者登入成功後,伺服器端按照一定規則生成一個Token令牌,Token是可變的,也可以是固定的(後面會說明);
將Token作為key,使用者資訊作為value放到快取中,設定有效時長(比如30分鐘內沒有訪問就失效);
將Token返回給APP端,APP儲存到本地儲存中以便請求介面時帶上此引數;
通過攔截器攔截所有涉及到使用者隱私安全等方面的介面,驗證請求中的Token引數合法性並檢查快取是否過期;
驗證通過後,將Token值儲存到執行緒儲存中,以便當前執行緒的操作可以通過Token直接從快取中索引當前登入的使用者資訊。

綜上所述,APP端要做的事情就是登入並從伺服器端獲取Token儲存起來,當訪問使用者隱私相關的介面時帶上這個Token標識自己的身份。伺服器端要做的就是攔截使用者隱私相關的介面驗證Token和登入資訊,驗證後將Token儲存到執行緒變數裡,之後可以在其它操作中取出這個Token並從快取中獲取當前使用者資訊。這樣APP不需要知道使用者ID,它拿到的只是一個身份標識,而且這個標識是可變的,伺服器根據這個標識就可以知道要操作的是哪個使用者。

對於Token是否可變,處理細節上有所不同,效果也不一樣。

Token固定的情況:伺服器端生成Token時將使用者名稱和密碼一起進行MD5加密,即MD5(username+password)。這樣對於同一個使用者而言,每次登入的Token是相同的,使用者可以在多個客戶端登入,共用一個Session,當使用者密碼變更時要求使用者重新登入;
Token可變的情況:伺服器端生成Token時將使用者名稱、密碼和當前時間戳一起MD5加密,即MD5(username+password+timestamp)。這樣對於同一個使用者而言,每次登入的Token都是不一樣的,再清除上一次登入的快取資訊,即可實現唯一使用者登入的效果。

為了保證同一個使用者在快取中只有一條登入資訊,伺服器端在生成Token後,可以再單獨對使用者名稱進行MD5作為Seed,即MD5(username)。再將Seed作為key,Token作為value儲存到快取中,這樣即便Token是變化的,但每個使用者的Seed是固定的,就可以通過Seed索引到Token,再通過Token清除上一次的登入資訊,避免重複登入時快取中儲存過多無效的登入資訊。 
本文轉載至http://www.myexception.cn/Java-other/2044891.html

相關文章