Using Cookie Authentication PHP

Store authentication status in a cookie or as part of a session. When a user logs in
successfully, put their username in a cookie. Also include a hash of the username and a secret
word so a user can't just make up an authentication cookie with a username in it:

$secret_word = 'if i ate spinach';
if (pc_validate($_REQUEST['username'],$_REQUEST['password'])) {
setcookie('login',
$_REQUEST['username'].','.md5($_REQUEST['username'].$secret_word));
}
 Discussion
When using cookie authentication, you have to display your own login form:
<form method="post" action="login.php">
Username: <input type="text" name="username"> <br>
Password: <input type="password" name="password"> <br>
<input type="submit" value="Log In">
</form>
You can use the same pc_validate( ) function from the Recipe 8.10 to verify the username
and password. The only difference is that you pass it $_REQUEST['username'] and
$_REQUEST['password'] as the credentials instead of $_SERVER['PHP_AUTH_USER'] and
$_SERVER['PHP_AUTH_PW']. If the password checks out, send back a cookie that contains a
username and a hash of the username, and a secret word. The hash prevents a user from
faking a login just by sending a cookie with a username in it.
Once the user has logged in, a page just needs to verify that a valid login cookie was sent in
order to do special things for that logged-in user:
unset($username);
if ($_COOKIE['login']) {
list($c_username,$cookie_hash) = split(',',$_COOKIE['login']);
if (md5($c_username.$secret_word) == $cookie_hash) {
$username = $c_username;
} else {
print "You have sent a bad cookie.";
}
}
if ($username) {
print "Welcome, $username.";
} else {
print "Welcome, anonymous user.";
}
If you use the built-in session support, you can add the username and hash to the session and
avoid sending a separate cookie. When someone logs in, set an additional variable in the
session instead of sending a cookie:
if (pc_validate($_REQUEST['username'],$_REQUEST['password'])) {
$_SESSION['login'] =
$_REQUEST['username'].','.md5($_REQUEST['username'].$secret_word));
}
The verification code is almost the same; it just uses $_SESSION instead of $_COOKIE:

unset($username);
if ($_SESSION['login']) {
list($c_username,$cookie_hash) = explode(',',$_SESSION['login']);
if (md5($c_username.$secret_word) == $cookie_hash) {
$username = $c_username;
} else {
print "You have tampered with your session.";
}
}
Using cookie or session authentication instead of HTTP Basic authentication makes it much
easier for users to log out: you just delete their login cookie or remove the login variable from
their session. Another advantage of storing authentication information in a session is that you
can link users' browsing activities while logged in to their browsing activities before they log in
or after they log out. With HTTP Basic authentication, you have no way of tying the requests
with a username to the requests that the same user made before they supplied a username.
Looking for requests from the same IP address is error-prone, especially if the user is behind a
firewall or proxy server. If you are using sessions, you can modify the login procedure to log
the connection between session ID and username:
if (pc_validate($_REQUEST['username'],$_REQUEST['password'])) {
$_SESSION['login'] =
$_REQUEST['username'].','.md5($_REQUEST['username'].$secret_word));