我想在登錄前添加一個「記住我」複選框選項PHP登錄系統:記住(永久cookie)
什麼是安全地存儲在用戶瀏覽器的cookie的最佳方式?
例如,Facebook上有自己的「記住我」複選框,這樣你每次進入facebook.com一次你在已經登錄。
我目前登錄使用簡單的會話。
我想在登錄前添加一個「記住我」複選框選項PHP登錄系統:記住(永久cookie)
什麼是安全地存儲在用戶瀏覽器的cookie的最佳方式?
例如,Facebook上有自己的「記住我」複選框,這樣你每次進入facebook.com一次你在已經登錄。
我目前登錄使用簡單的會話。
這個問題被問到很多,這裏有一些鏈接給你。
還有在回答這個問題集中到一起一些重要的資源:The Definitive Guide To Website Authentication
更好的解決方案:[在具有長期持久性的PHP應用程序中實現安全用戶身份驗證](https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence#title.2 )(2015) – 2015-05-11 05:15:40
更新(2017年8月13日):要理解爲什麼我們分離
selector
和token
,而不是僅僅使用token
,請閱讀SELECT查詢this article about splitting tokens to prevent timing attacks。
我要提取這篇博客about secure long-term authentication勾畫的戰略,因爲這涵蓋了大量的地面,我們只在"remember me"部分感興趣。
我們希望從我們的用戶表一個單獨的表看起來像這樣(MySQL的):
CREATE TABLE `auth_tokens` (
`id` integer(11) not null UNSIGNED AUTO_INCREMENT,
`selector` char(12),
`token` char(64),
`userid` integer(11) not null UNSIGNED,
`expires` datetime,
PRIMARY KEY (`id`)
);
這裏最重要的事情是selector
和token
是分開的領域。
後如果沒有random_bytes()
做什麼,只是搶random_compat副本。
if ($login->success && $login->rememberMe) { // However you implement it
$selector = base64_encode(random_bytes(9));
$authenticator = random_bytes(33);
setcookie(
'remember',
$selector.':'.base64_encode($authenticator),
time() + 864000,
'/',
'yourdomain.com',
true, // TLS-only
true // http-only
);
$database->exec(
"INSERT INTO auth_tokens (selector, token, userid, expires) VALUES (?, ?, ?, ?)",
[
$selector,
hash('sha256', $authenticator),
$login->userId,
date('Y-m-d\TH:i:s', time() + 864000)
]
);
}
if (empty($_SESSION['userid']) && !empty($_COOKIE['remember'])) {
list($selector, $authenticator) = explode(':', $_COOKIE['remember']);
$row = $database->selectRow(
"SELECT * FROM auth_tokens WHERE selector = ?",
[
$selector
]
);
if (hash_equals($row['token'], hash('sha256', base64_decode($authenticator)))) {
$_SESSION['userid'] = $row['userid'];
// Then regenerate login token as above
}
}
我們用9個字節爲我們選擇隨機數據(編碼爲12個字符的base64)的。這提供密鑰空間的72位,因此2 抗衝突性(生日攻擊),其比爲16
一個因子我們的存儲容量(integer(11) UNSIGNED
)放大我們使用的33個字節(264位)的位我們的實際認證者的隨機性。這在所有的實際情況下都是不可預測的。
我們將驗證器的SHA256哈希存儲在數據庫中。這可以緩解信息泄露後用戶冒充的風險。
我們重新計算存儲在用戶cookie中的驗證器值的SHA256哈希值,然後使用hash_equals()
將其與存儲的SHA256哈希值進行比較以防止計時攻擊。
我們將選擇器與驗證器分開,因爲數據庫查找不是恆定時間。這消除了時間泄漏對搜索造成的潛在影響,而不會造成嚴重的性能下降。
您可以查看https://github.com/delight-im/PHP-Auth及其來源,瞭解如何實現* secure *「記住我」功能。基本上,只需在cookie中存儲一些非常長的*(即很多熵)的隨機數據串。當用戶訪問您的頁面時,請在跟蹤這些標記的數據庫中檢查「標記」。如果令牌有效,則認證用戶。 – caw 2016-07-13 00:01:25