認證授權包含2個方面:
(1)訪問某個資源時必須攜帶用戶身份信息,如:用戶登錄時返回用戶access_token,訪問資源時攜帶該參數。
(2)檢查用戶是否具備訪問當前資源(url或數據)的權限:訪問資源時檢查用戶權限。
在REST架構中,access_token被定義為用戶身份標識,用於對資源訪問授權,只允許系統合法用戶訪問資源。具體來說:
- 必須在每次訪問時都攜帶access_token參數,參數位置可以位於HTTP消息頭(HTTP Basic Authentication),也可放在請求參數列表中。
- 如果在訪問請求中不存在access_token參數,或者驗證access_token不合法(不存在或者不正確),拒絕訪問,必須強制用戶登錄。
如何生成安全有效的用戶access_token?
acces_token作為用戶身份標識,必然與數據庫中的用戶一一對應,即:<access_token : user_id>。
在網絡通信中,一切數據都是透明的,都能被抓包截獲,所以必須保證access_token具備如下特性:
1. access_token需要滿足分布式環境下的全局唯一性。
2. access_token中不應該包含用戶信息,如果將用戶id編碼到access_token中很容易泄露系統用戶信息(通常用戶id都是自增長的,很容易曝露系統當前用戶規模等信息)。
3. access_token應該是動態變化的,即:用戶每次登錄時得到的access_token值都與上一次登錄不同。這樣保證參數沒有規律性,避免被用於網絡攻擊。
4. access_token應該具備一定特征,用於參數合法性驗證,如:長度必須滿足30個字符。
參照如上需求,可以按照如下方式設計access_token:
(1)用戶登錄時,動態生成UUID作為該用戶的access_token,同時以access_token為key,用戶id為value存入redis。
(2)用戶訪問資源時攜帶access_token,解析驗證請求參數。
(3)如果access_token在redis中不存在,則說明用戶還未登錄,強制用戶登錄;轉到(1)。
(4)如果access_token不合法(如字符長度不滿足),強制用戶重新登錄;轉到(1)。
(5)驗證access_token通過,繼續其他權限驗證或者資源訪問。
此外,根據業務場景可以作如下約定以增強access_token安全性:
1. 設置access_token超時時間,即:超過一定時間之后就必須讓access_token失效,強制用戶重新登錄。
2. 使用HTTP Basic Authentication,將access_token放在http消息頭中而不是直接放在請求參數里,這樣做更加規范。
3. 由於UUID會使用時間戳,所以需要對集群內服務器進行時鍾同步。
注意:
JDK提供的默認UUID實現是基於名字空間的UUID(UUID Version 3)和基於偽隨機數的UUID(UUID Version 4),很難保證在分布式環境下是全局唯一的。一個可選的開源Java UUID實現組件:
https://github.com/cowtowncoder/java-uuid-generator Java Uuid Generator (JUG),提供基於時間和MAC地址的UUID Version 1實現
當然,如果在實際的業務系統中能保證名稱唯一,比如用戶手機或者郵箱,那么可以直接使用JDK基於名稱空間的UUID V3實現。
之所以選擇UUID作為access_token實現,基於如下考慮:
(1)性能:UUID生成在本地完成,高效。
(2)簡單有效:只要保證access_token全局唯一即可,且可以動態變化。
實際上,實現認證最優雅的方式應該是使用JWT,這是一個Token標准。
【參考】
https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E5%94%AF%E4%B8%80%E8%AF%86%E5%88%AB%E7%A0%81 UUID
https://www.zhihu.com/question/34876910 UUID是如何保證唯一性的?
http://blog.csdn.net/fengshizty/article/details/48754609 App開放接口api安全性—Token簽名sign的設計與實現
http://www.cnblogs.com/QLeelulu/archive/2009/11/22/1607898.html 訪問需要HTTP Basic Authentication認證的資源的各種語言的實現
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization
https://zxc0328.github.io/2015/11/04/http-basic-auth/ Http Basic Authorization的使用