網站登錄鑒權的實現


什么是網站鑒權,目的是什么?
一般來說,一個網站不可能只有一種操作權限。舉個例子,可能存在未登錄的操作權限,登錄的操作權限,以及管理
員的操作權限等。網站鑒權的目的就是用戶在進行操作前,對用戶的身份進行識別並判斷其是否具有該操作權限的過
程。

網站鑒權的幾種方式
這里我們將問題簡單化,即操作權限只區分用戶是否進行了登錄。

Session方式實現
(1)Session實現鑒權
1>用戶首先進行登錄,如登錄成功的話,后台會生成一個唯一的sessionId,並在后台存儲對應的用戶信息
(redis,數據庫等等),並將sessionId寫到Cookie。
2>下次該瀏覽器訪問時,會首先判斷Cookie,進而確定該用戶是否進行了登錄操作。
(2)Session一致性問題
即需要將在服務器存儲的用戶信息放在一塊兒(同一個redis,mysql等),否則可能出現在一台機器上登錄,
並且在該機器上保存了數據,但下一次請求訪問到另一個服務器時,需要重新進行登錄的情況。

JWT以及具體實現
(1)JWT鑒權的簡單流程
JWT分為三部分:Header(包含加密方式等),Payload(包含用戶必要信息,以及過期時間等),
Signature(由前兩部分生成)。
1>用戶登錄成功后,后台根據用戶信息加上一個用戶唯一的密鑰值,生成一串字符串,即Token串,將其設置
在Cookie中;
2>用戶下次帶Token訪問,系統會先根據前兩部分以及密鑰值,對Token進行有效性以及正確性的驗證,如果
驗證通過的話,再執行下一步操作...
(2)關於鑒權時機的思考
下面提供兩種方式,大家可以根據具體的網站需求進行選擇:
1>將接口分為需要進行鑒權的接口(auth),不需要進行鑒權的接口(api),然后通過過濾器對auth接口
進行統一的處理,即登錄進行訪問,未登錄跳回登錄頁等等邏輯。
2>上面做法存在一個問題,就是當接口中出現無法界定的接口,即登錄未登錄都可以進行訪問。那么,按照上
面的方法就只能對接口進行拆分,分成api和auth接口。
所以,另一種方式就是索性不使用過濾器進行處理,當需要進行登錄才能訪問,或無法界定的接口的時
候,對token進行驗證以及獲取,再接着進行下面的邏輯處理。
(3)關於Token刷新的問題
一般Token的有效時間設置為1-2個小時,那么,如果過期之后,就需要重新登錄獲取Token。為了避免這種
情況,我們可以為Token設置一個刷新有效時間,只要Token在這個刷新有效時間內,使用舊的Token進行訪
問,就會給它返回一個新的Token。這樣,問題就可以解決。

oauth鑒權,了解一下(應用:第三方登錄)
oauth簡單來說,就是為了解決一個應用(客戶端)中為了獲取另一個應用(服務提供商)資源,而不需要用戶向
客戶端提供服務提供商賬號密碼信息的這樣一個問題。客戶端與服務提供商之間,有一個應用授權層,客戶端攜帶
Token通過授權層獲取服務提供商的資源。

第三方登錄就采用的是oauth2進行授權的,這里有通過Go語言實現QQ和Github第三方登錄的代碼

總結
我們這里只是簡單的探討了下關於鑒權的幾種方式,在實際的開發中,由於安全性,以及網站的復雜性,可能會存
在多種不同的用戶權限等等,那么,就可能需要對這些方式進行一定的設計和修改。

原文鏈接:https://blog.csdn.net/leeezm/article/details/80464847

 

 

 

 

一、概述

 登陸和認證是什么?都是在鑒別用戶的身份。如何鑒定識別出這是哪個用戶?或者說,有什么方式只有用戶自己知道(夠安全),又能說出這是他自己?於是就有了"用戶名+密碼"、"用戶名+手機號" 的方式出現。下面主要分析 “用戶名+密碼”的登陸鑒權方式:

  1. 出於安全考慮,我們不可能在所有的請求里都使用“用戶名+密碼”。
  2. "用戶名+密碼"不能存儲在任何地方,最安全的方式就是存放在用戶自己的腦子里,也就是說如果要使用 “用戶名+密碼” 就得讓用戶自己提供。

 那么我們如何做到可以不用提供用戶名和密碼呢?我們在用戶登錄的時候,根據用戶的身份信息去生成一種能標記用戶的 token。

 有了認證信息 token 以后,新的問題就是如何保證這個 token 是安全的呢?如果其他人拿到了這個 token 就能偽造用戶身份了。解決方案就是鑒定這個 token 是不是用戶本人在使用,一般我們通過以下方式,如果我們能保證下面的兩種驗證信息是一直都沒變或者在可接受的范圍內,我們就能認為這個用戶一直在使用我們下發的 token。

  1. 位置信息(ip、經緯度)
  2. 設備信息

 現在我們已經做到了 token + (位置、設備信息)來鑒定用戶的身份。如果我們每次請求都要鑒定這些信息來確認用戶身份,勢必影響我們服務的性能。那么如何減少這樣的判定呢?

  1. 服務端隨機或者定時選定一次請求鑒定
  2. 客戶端定時請求一次鑒定

 第一種方式不建議,服務器維護每個用戶定時復雜,隨機可能會有大量用戶同時鑒定的性能問題。那么就是第二種了,客戶端定時請求一次鑒定,服務端需要強制客戶端定時請求一次鑒定,而這個定時時間就是一個安全因素,如果在期間 token 泄露就會造成用戶信息安全問題,時間不能太長,也不能太短,參考微信的是 7200s 就是 2 小時。

 那么如何強制客戶端每隔一段時間做一次驗證呢?很簡單,我們給 token 設個有效時間,到失效時間客戶端就必須請求一次新的 token,於是就有了 refresh token。

二、鑒權方式

 用戶登錄后,每次請求服務時客戶端請求都要包含鑒權信息,服務端根據鑒權信息查詢用戶信息和其合法性。目前鑒權信息可以有如下方式:

1. 集中式 session 方式

 在登陸完成后,服務端將返回作為認證鑒權的隨機不重復 token,客戶端每次請求帶上這個 token(一般放在請求的 header 里面)。服務端通過 token 查詢到 token 對應的用戶信息。

2. 令牌方式

 登陸完成后,服務端根據用戶信息和其他安全因素加密生成一個安全令牌(也就是 JWTS,JSON Web Tokens),該令牌中包含了用戶的身份信息,在認證鑒權時只需驗證令牌的合法性即可,解密即可取到用戶信息。

3. 比較

鑒權方式 優點 不足
集中式 session 方式 1. 服務端維護用戶狀態,可以管理用戶狀態,沒有失效和用戶信息一致問題;

2. 安全性相對較高

1. 服務端維護 Session 狀態,根據 Token 獲取用戶信息需要極高的性能要求
令牌方式 1. 客戶端記錄用戶狀態,服務是無狀態的,沒有集中式的性能問題。

2. 業務解耦,鑒權邏輯相對簡單的多,令牌方式在技術實現性能和可靠性上也相對容易些

1. 令牌強制失效或者續簽問題,令牌強制失效或更新需要額外工作(比如封禁用戶)

2. 當用戶信息更新后,令牌里的用戶的同步問題

三、鑒權實現方案

1. 集中式 session 方式流程時序

  1. 客戶端在未登錄的狀態下請求業務服務,在網關沒有獲取到認證信息時直接返回 401,告知客戶端需要登錄。
  2. 客戶端使用“手機號+密碼”、“手機號+驗證碼”的方式請求登陸服務。
  3. 網關發現是登陸服務后,請求登陸認證服務。
  4. 登陸認證服務通過手機號碼查詢用戶信息,同時生成 token。
  5. 返回網關 token,網關將 token 返回給客戶端。
  6. 客戶端帶着 token 請求網關,網關將 token 傳給鑒權服務,鑒權服務通過 token 查詢用戶信息並返回給網關,網關將用戶信息轉給業務服務,完成接下來的業務流程。

2. 令牌方式流程時序

  1. 客戶端在未登錄的狀態下請求業務服務,在網關沒有獲取到認證信息時直接返回 401,告知客戶端需要登錄。
  2. 客戶端使用“手機號+密碼”、“手機號+驗證碼”的方式請求登陸服務。
  3. 網關發現是登陸服務后,請求登陸認證服務,同時生成 token(JWT信息),並將 token 返回給客戶端。
  4. 客戶端帶着 token 請求網關,網關根據 token(JWT信息)解密得到用戶信息,並將用戶信息轉給業務服務,完成接下來的業務流程。

四、鑒權技術方案

1. 集中式Session鑒權技術方案

集中式Session鑒權驗證用戶身份有如下的實現方式:

實現 說明 優點 缺點
RPC調用 網關通過RPC調用鑒權服務,通過token獲取用戶信息 架構邏輯簡單,不需要額外工作 增加響應 RT
Redis 直讀 網關直接讀取鑒權服務的 Redis,驗證並獲取用戶信息 高性能 需要網關也集成鑒權驗證邏輯,並且維護 Redis 的配置
Nginx Lua 在 Nginx 里通過 lua 腳本實現鑒權邏輯 性能最好 1. 在網關之前,對簽名無效的請求也需要做鑒權驗證。

2. Nginx 改造,lua 開發成本

2. 令牌方式鑒權技術方案

令牌方式鑒權的實現就簡單的多, 網關直接解析 JWT 信息獲取用戶信息,然后帶着用戶信息去請求業務數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM