[英]saving authentication token in cookie (Django Rest Framework + React)
所以,正如標題所說,我正在使用 Django Rest Framework,結合 React。
我使用令牌身份驗證對用戶進行身份驗證。 現在我面臨一個問題。 當我重新加載頁面(例如按 F5 鍵)時,所有狀態都消失了,在這種情況下我無法保存令牌,需要用戶再次登錄。
我想過將令牌存儲在 cookie 中,但這似乎不太安全。
還有其他類似的問題,但沒有答案真正解釋這是多大的安全風險。 我認為它相當高,因為擁有令牌似乎足以作為后端的某個人進行身份驗證。
所以,我的問題是:我假設將我的身份驗證令牌存儲在 cookie 中是不安全的嗎?
注意:我正在考慮切換到基於會話的身份驗證,但我寧願保護我的工作並保留令牌身份驗證。
我忘記了我的舊答案仍然在互聯網上獲得了一些牽引力……而且我后來意識到這部分是錯誤的。
I thought about storing the token in a cookie, but that doesn't seem very safe.
如果操作正確,它就足夠安全了。 是的,任何對系統有物理訪問權限的人仍然可以讀取 cookie。 更多關於這個下面。
讓我們澄清一件事,絕對有必要在客戶端(在本例中為瀏覽器)存儲一些數據,並通過 API 調用發送這些數據以驗證用戶身份。 讓我們稱這些數據為“令牌”。
當您在 API 調用中發送此令牌時,對系統具有物理訪問權限的任何人都可以查看它。 此外,沒有必要對其進行加密,因為...
有什么選擇? 老實說,就這樣吧。 大多數網站都是這樣工作的(幾乎)。 除非該網站持有一些非常敏感的信息。 在這種情況下,可能會研究基於時間的密碼、基於硬件的密碼、生物特征? 這些方法主要將安全保存密鑰的責任轉嫁給用戶。
你當然可以,讓它更安全。 以下是一些提示:
考慮到這一點,讓我們談談存儲令牌。
我們只需要確保其他網站、惡意腳本和軟件無法訪問存儲的令牌。 (如上所述,用戶始終可以讀取令牌。)
您可以將其存儲在cookies
或localStorage
。 兩者都可以正常工作,但localStore
旨在存儲更大的數據。 Cookies
最多可以存儲 4096 字節的數據 - 這足以存儲令牌。 Cookies
在處理 SSR(服務器端渲染)時也有幫助。 不過,在 React 中處理 cookie 可能會很棘手。 (提示:試試 next.js,它內置了對帶有 React 的 cookie 和 SSR 的支持。)
如果有幫助,您還可以在 cookie 中指定過期時間。
TL;DR:使用Cookies
非常好。 只要正確使用它。
感謝@ShayanSalehian 指出這一點: LocalStorage is subject to XSS and cookie is subject to CSRF. So I think using cookies + CSRF is the most secure way even in TokenAuthentication for storing tokens on client...
LocalStorage is subject to XSS and cookie is subject to CSRF. So I think using cookies + CSRF is the most secure way even in TokenAuthentication for storing tokens on client...
這也是我不得不面對的事情。 在這個過程中失去了幾個晚上的睡眠。
免責聲明:我不是任何安全專家。 只是有點痴迷(閱讀:偏執)。
簡短版本(回答您的問題):我最終使用 window.localStorage 來存儲令牌。 雖然我不相信這是最好的做法,但這不僅僅是關於“存儲”部分 - 閱讀長版以了解更多信息。
長版:首先,讓我們澄清一些事情。 React 更像是一個移動應用程序,而不是一個網頁/網站。 我不是在談論 React Native - 我的意思是React.js 。
為什么我說它更像是一個移動應用程序而不是一個網站? 傳統網站通常使用基於會話的身份驗證,瀏覽器/服務器通常為此准備。 顯然,這是一項毫不費力且無縫的任務。
在移動應用程序(或客戶端獨立應用程序)中,您需要維護某種令牌來基本上告訴服務器“嘿,是我!我前段時間訪問過。這是我的身份證。請讓我進去好嗎?” . 問題是,很難在客戶端保持令牌安全。 在 Android v4.3 之前,Android 本身並沒有提供任何安全的方式來存儲身份驗證令牌。 這也不夠安全,所以他們不久前引入了硬件支持的密鑰庫。 這就是為什么某些應用程序不能(並且仍然不能)在有 root 權限的設備上運行的原因。 在此處閱讀更多相關信息: https : //stackoverflow.com/a/19669719/3341737
與 React/獨立 Web 應用程序相比,谷歌(在某種程度上)控制着 Android 客戶端。 他們實現基於硬件的密鑰庫相對容易。 對於網絡應用程序,有大量的瀏覽器,有數百個版本等等。
回到 window.localStorage。 與 Cookie 類似,localStorage 對每個域都是隔離的。 由於它是一個較新的 API,因此它的設計方式比舊的 Cookie 更好。
加密密鑰沒有意義(盡管您可能會混淆它),因為您還需要將解密密鑰存儲在本地某個地方。 因此,如果有人可以訪問令牌,他們也可以訪問解密密鑰。
這個問題的第二個方面(以及為什么“存儲”不是唯一的問題)是 - 你真的想保護誰的令牌?
為什么不? 因為您需要隨每個請求發送令牌 - 每個請求發送的數據在瀏覽器網絡檢查器中可用。 因此,無論您在何處以及如何存儲令牌,它都可能被具有 PC 物理訪問權限的人竊取。
為什么不是餅干? 兩個原因(實際上是 1 個):
window.localStorage.setItem('key', 'value')
)。 此外,與 Cookie 相比,最大大小限制要高得多。因此,window.localStorage 對我來說似乎是一個可行的選擇。 如果您有更好的解決方案,請啟發我。
話雖如此,這並不意味着您不能提高安全性。 以下是一些建議:
下一個方法是什么:在 OAuth https://auth0.com/docs/tokens/refresh-token/current 中存儲不是令牌而是refresh_token
?
您應該決定為您的安全需要保留哪些超時,因此每次令牌死亡或為空后,您都可以嘗試恢復會話是存儲在 cookie 中的refresh_token
即使潛在的破解者會在 const 超時后獲得 refresh_token 也沒有意義
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.