首先,只是跟蹤。在那之後,我們將採取「記住我」功能的護理。
要知道,如果有一個人登錄,你只要看看$_SESSION
陣列。那裏的一切都是因爲你之前把它放在那裏。因此,在處理登錄表單時,如果用戶名&密碼正確,那麼您將在會話($_SESSION['username'] = $username;
)中存儲用戶名,用戶標識或任何內容。
每當用戶加載任何頁面,你只需檢查
if (isset($_SESSION['username'])) {
// $_SESSION['username'] is logged in
} else {
// nobody is logged in
}
有沒有需要存儲在$_SESSION
密碼(實際上,爲了安全起見,最好是不存儲任何地方,除了在散列數據庫)。
現在,「記住我」的功能。首先,一些注意事項:
- 任何用戶都可以修改其瀏覽器的Cookie,所以你需要確保發送到應用程序的餅乾已經不篡改。
- 用戶可以檢查在公共電腦(圖書館等),所以你需要一個系統來使其無效。
- 如果用戶退出應用程序,則記住他/她的cookie必須被刪除。
對於第一點,想象一下在cookie上存儲用戶的用戶名以「記住」(非常INSECURE !!)。這意味着,如果任何用戶爲內容爲'joe'的web應用程序創建了一個cookie,則您的應用程序會認爲該用戶joe在該計算機中被記住,因此授予訪問此攻擊者的權限,就好像他/她是joe一樣。所以,我們需要以某種方式隱藏/散列cookie。
對於第二點,在某些計算機上使「記住我」無效,我們將以某種方式使用密碼。如果某個用戶想要使所有他/她可能已經檢查了「記住我」複選框的計算機失效,他/她所要做的就是更改他/她的密碼。這也意味着,如果他/她更改了密碼,出於同樣的原因,所有保存的用於他/她帳戶的登錄都將失效。但更好的安全比對不起...
因此,當您處理登錄名和用戶名和密碼是正確的,並且「記住我」選項被選中時,除了在會話中保存用戶名之外,在發送給用戶的cookie中用戶名密碼(以及一些鹽)的散列。此外,您還需要在Cookie中以純文本形式(或以可逆方式加密)存儲用戶名,以知道哪個用戶正嘗試通過Cookie「登錄」,並檢查cookie中用戶名爲&的密碼的哈希值用戶名&數據庫中的密碼。如果該檢查是正確的,則您將用戶名存儲在會話中,不要再檢查此用戶的cookie(至少在本次會話中)。
因此,總體而言你的代碼可能是這樣的:
的login.php
if (check_login($_POST['username'], $_POST['password'])) {
// login correct
$_SESSION['username'] = $_POST['username'];
if (isset($_POST['remember_me'])) {
// we hash the password because we **NEVER** store it in plain text anywhere
// so when we would like to check if the cookie value is correct, we will not
// be able to do so if the hash in the cookie was done from the plaintext
// password.
$value = sprintf('%s:%s', $_POST['username'], md5($_POST['username'].hash_password($_POST['password'])));
setcookie('rememberme', $value);
}
redirect('/your/home/page.php'); // view Post/Redirect/Get design pattern
} else {
// login incorrect, show error message and whatever...
}
在每一個php文件的開頭(或更好,在包含文件來引導你的應用程序)
if (isset($_SESSION['username'])) {
// $_SESSION['username'] is logged in, proceed as you wish
} else if (isset($_COOKIE['rememberme'])) {
// this user has checked the remember me feature some time ago in a previous login.
// let's check if it is valid.
list($username, $hash) = explode(':', $_COOKIE['rememberme']);
// we need to get the password hash stored for this user (remember you **NEVER** store passwords in plain text
$pwd_hash = obtain_password_hash_from_username($username);
if ($hash == sprintf('%s:%s', $username, md5($username.$pwd_hash))) {
// yeah, the user remembered is correct. We'll save it to the session to not do this shit again
$_SESSION['username'] = $username;
} else {
// the cookie value is not correct so maybe an attacker is trying to fool us,
// or the user changed his password. Whatever it is, we remove the cookie
// because it's no longer valid
setcookie('rememberme', '', time() - 3600);
}
} else {
// this user is neither logged in nor "remembered"
}
散列用戶密碼的方法取決於您。你可能會喜歡普通的md5或沙,醃製的md5或沙(更好)或一些耗費時間的方法,如河豚(推薦)。 爲了散列我使用普通md5的cookie,但你可以選擇任何早期描述的方法。
我認爲就是這樣。
可能有用:[用戶會員使用PHP](http://net.tutsplus.com/tutorials/php/user-membership-with-php/) – drudge 2011-02-23 19:14:48
@Prashant:請寄給我[email protected],需要私下討論。閱讀後請刪除此內容。 – 2012-03-04 10:00:48