基於Token認證的多點登入和WebApi保護

weixin_34391854發表於2018-12-12

  在文章中有錯誤的地方,或是有建議或意見的地方,請大家多多指正,郵箱: linjie.rd@gmail.com

  一天張三,李四,王五,趙六去動物園,張三沒買票,李四製作了個假票,王五買了票,趙六要直接FQ進動物園

  到了門口,驗票的時候,張三沒有買票被拒絕進入動物園,李四因為買假票而被補,趙六被執勤人員抓獲,只有張三進去了動物園

  後來大家才知道,當一個使用者帶著自己的資訊去買票的時候,驗證自己的資訊是否正確,那真實的身份證(正確的使用者名稱和密碼),驗證通過以後通過身份證資訊和票據列印時間(使用者登入時間)生成一個新的動物園參觀票(Token令牌),給了使用者一個,在動物園門口也儲存了票據資訊(相當與客戶端和服務端都儲存一份),在進動物園的時候兩個票據資訊對比,正確的就可以進動物園玩了

  這就是我理解的Token認證.當然可能我的比喻不太正確,望大家多多諒解

 

   下面是我們在服務端定義的授權過濾器

  思路是根據切面程式設計的思想,相當於二戰時期城樓門口設立的卡,當使用者想api發起請求的時候,授權過濾器在api執行動作之前執行,獲取到使用者資訊

  如果發現使用者沒有登入,我們會判斷使用者要訪問的頁面是否允許匿名訪問

    使用者沒有登入但是允許匿名訪問,放行客戶端的請求

    使用者沒有登入且不允許匿名訪問,不允許通過,告訴客戶端,狀態碼403或401,請求被拒絕了

  如果發現使用者登入,判斷使用者的良民證(Token令牌)是真的還是假的

    使用者登入,且良民證是真的,放行

    發現良民證造價,抓起來,不允許訪問

當然,這裡可以加許可權,驗證是否有某個操作的許可權

好了,服務端有驗證了,客戶端也不能拉下啊,客戶端使用了動作過濾器,在使用者操作之前或使用者操作之後驗證登入資訊(這裡可以加許可權,驗證是否有某個操作的許可權)  

客戶端驗證思路和服務端驗證差不多


下面是客戶端驗證程式碼:

 

但是有良民證也不能也不能無限制的待在城裡啊,我們做了一個時效性,在城市裡什麼時也不做到達一定的時長後得驅逐出城啊(類似與遊戲中的掛機超過一定時間後T出本局遊戲)

在這裡使用的Redis記錄良民證(Token),思路是使用者登入之後生成的新的Token儲存在Redis上,設定儲存時間20分鐘,當有使用者有動作之後更新Redis儲存有效期

 下面是服務端驗證token的,token有效,從新寫入到Redis

 

以上就是Token認證

現在說說單點登入的思路

張三登入了qq:123456,生成了一個Token以鍵值對的方式儲存在了資料庫,鍵就是qq號,值就是qq資訊和登入時間生成的一個Token

李四也登入了qq123456,qq資訊是一致的,但是qq登入時間不同,生成了一個新的Token,在儲存的時候發現Redis裡已經存在這個qq的鍵了,說明這是已經有人登入了,在這裡可以判斷是否繼續登入,登入後新的Token資訊覆蓋了張三登入QQ生成的Token,張三的Token失效了,當他再次請求的時候發現Token對應不上,被T下線了

多點登入也是,可以通過qq號加客戶端型別作為鍵,這樣手機qq登入的鍵是 123456_手機,電腦登入的鍵是123456_電腦,這樣在儲存到Redis的時候就不會發生衝突,可以保持手機和電腦同時線上

但是有一個人用手機登入qq 123456了,就會覆蓋redis中鍵為123456_手機的Token資訊,導致原先登入那個人的資訊失效,被強制下線

 

來展示程式碼

判斷是否可以登入

客戶端型別實體

這是我們的客戶端型別:

  

獲取token需要的使用者資訊和登入時間的實體Model

  這是我們的使用者Model

  

生成Token用的實體

登入成功,通過JWT非對稱加密生成Token

下面是JWT加密和解密的程式碼

將獲取到的Token儲存到Redis

相關文章