1. 程式人生 > WINDOWS開發 >Api介面登入的鑑權方案

Api介面登入的鑑權方案

Api介面登入的鑑權方案
web登入和前後端分離方式的登入是不一樣的,web登入成功主要靠的session,一但登入成功後客戶端就會儲存一個session_id,這樣以後每次使用者訪問網頁都會帶著session_id,這樣就能取得存放在服務端的session資料。
app登入就不能使用session,所以我們這裡可以使用登入成功後要產生一個token值,以後使用者每次訪問app都要在header頭帶著這個token值,而這個token值需要一個過期時間。這個token值可以使用兩種方案,一、可以在使用者表上加上一個token欄位和一個過期時間欄位,二、可以使用JWT(json web token)這樣就不需要將token值存入到資料庫中
1 使用資料庫
使用者第一次註冊成功後,往資料庫中插入一條資料,同時生成一個token和token的過期時間,token的生成一定要具有唯一性。(token的生成可以使用md5(uniqid()));同時將token返回給客戶端,客戶端將token存起來,以後每次訪問都帶上這個token,這樣我們就能先檢測token是否存在,如果存在就可以查詢使用者資訊,查到後然後對比過期時間就行,如果token不存在或者token不正確,或者過期返回重新登陸,登陸後也要重新生成token和token的過期時間,返回給客戶端。
但是上面還是有風險,如果網路包中途被別人截獲了,別人就可以傳送http請求了,(當然我們已經做了基本的引數的驗證,每次只能驗證一次),我們的token也可像sign一樣,當我們將token值返回給客戶端後,以後再發送請求給app時我們不用帶上token,帶上的是token和時間戳一起通過AES演算法加密的access_user_token,這樣我們每次訪問access_user_token 都是不一樣的,我們在服務端驗證時,首先判斷傳遞access_user_token,如果有我在判斷在redis中有無access_user_token值,如果有說明被驗證過了,這個網路包就不安全了,如果沒有,我們將access_user_token存入redis,然後進行解密,獲得token後從資料庫中查詢。如果解密失敗或者,資料庫中沒有資料或者時間過期了讓使用者重新登陸
2 使用JWT
我們也可以使用jwt,jwt是一種json web token ,當我們登陸成功或者註冊成功後,我們可以使用jwt加密演算法將使用者的id通過jwt進行加密生成一個token值,我們可以把這個token值存入到客戶端,這樣客戶端每次請求都會帶上token值,我們的服務端拿到這個token值進行解密,如果解密失敗或者時間過期,我們就讓他重新登陸,如果解密成功我們就能獲取使用者的user_id,這樣我們就能查到使用者的資訊了。
但是上面還是有風險,如果網路包中途被別人截獲了,別人就可以傳送http請求了,(當然我們已經做了基本的引數的驗證,每次只能驗證一次),我們的token也可像sign一樣,當我們將token值返回給客戶端後,以後再發送請求給app時我們不用帶上token,帶上的是token和時間戳一起通過AES演算法加密的access_user_token,如果有我在判斷在redis中有無access_user_token值,如果有說明被驗證過了,這個網路包就不安全了,如果沒有,我們將access_user_token存入redis,然後進行解密,獲得token後再使用jwt解密獲得使用者資訊(比如使用者的user_id)然後再從資料庫中查詢使用者資訊。如果解密失敗或者資料庫中沒有資料或者時間過期了讓使用者重新登陸。可以參考:
https://www.cnblogs.com/yehuisir/p/11521165.html

技術分享圖片
token和refresh_token的使用讓我們的app登入狀態永久性掛起。
即使是這樣,不論我們使用哪種方式,token的過期時間原理上可以說是越短越安全,那麼存在的問題就是token有一個過期時間,那麼過期之後是不可能讓使用者重新輸入使用者名稱和密碼來重新獲取token的,那樣完全違背了提升體驗的初衷,相當於此功能是一個累贅了;
在token過期的情況,我們可以使用儲存在手機本地的refresh_token去後臺重新整理一下token,重新獲取一組令牌資訊,覆蓋掉以前儲存在手機上的令牌資訊,這也算是提升了一點安全性,為避免以前的令牌資訊如果真落入別人之手
下面的例子是我用vue和jwt的案例
使用者登入成功後我們同時生成token和refresh_token,token的時間是7200秒,refresh_token的時間是30天,為了後期拿refresh_token生成新的token方便,token中加密的資料和refresh_token加密的資料是一樣的
技術分享圖片

我們每次都要驗證token,如下圖是驗證token的中介軟體
技術分享圖片
我們的客戶端收到返回50000的狀態碼是token不存在或者token錯誤,必須要重新登入,收到的50001的狀態碼是因為token過期,token過期後我們需要使用refresh_token 重新獲得新的token和refresh_token
技術分享圖片
技術分享圖片
技術分享圖片
下面是驗證refresh_token的中介軟體
技術分享圖片
如果驗證refresh_token的中介軟體通過後重新生成新的token和refresh_token
技術分享圖片
這樣就能實現我們的app上只需要登入一次,我們就不需要登入了,除非在30天內我們沒有操作過我們的app導致refresh_token也失效了。