PHP Web Fundamentals
Using Cookie Authentication
Problem
You want more control over the user login procedure, such as presenting your own login form.Solution
Store authentication status in a cookie or as part of a session. When a user logs in successfully, put her username (or another unique value) 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 (validate($_POST['username'],$_POST['password'])) {
setcookie('login',
$_POST['username'].','.md5($_POST['username'].$secret_word));
}
Discussion
Example Sample cookie authentication 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 validate() function to verify the username and password. The only difference is that you pass it $_POST['username'] and $_POST['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. shows one way to do this.
Example Verifying a login cookie
unset($username);
if (isset($_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 (isset($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.
Example Storing login info in a session
if (validate($_POST['username'],$_POST['password'])) {
$_SESSION['login'] =
$_POST['username'].','.md5($_POST['username'].$secret_word);
}
Example Verifying session info
unset($username);
if (isset($_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 using code such as that.
Example Connecting logged-out and logged-in usage
if (validate($_POST['username'], $_POST['password'])) {
$_SESSION['login'] =
$_POST['username'].','.md5($_POST['username'].$secret_word);
error_log('Session id '.session_id().' log in as '.$_POST['username']);
}
One danger of using session IDs is that sessions are hijackable. If Alice guesses Bob’s session ID, she can masquerade as Bob to the web server. The session module has two optional configuration directives that help you make session IDs harder to guess. The session.entropy_file directive contains a path to a device or file that generates randomness, such as /dev/random or /dev/urandom. The session.entropy_length directive holds the number of bytes to be read from the entropy file when creating session IDs.
No matter how hard session IDs are to guess, they can also be stolen if they are sent in clear text between your server and a user’s browser. HTTP Basic authentication also has this problem. Use SSL to guard against network sniffing.
No comments:
Post a Comment