PHP
  Home arrow PHP arrow Page 5 - Professional PHP Programming
Dev Shed Forums 
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Sun Developer Network 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Moblin 
JMSL Numerical Library 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PHP

Professional PHP Programming
By: Dev Shed
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 26
    2000-04-13

    Table of Contents:
  • Professional PHP Programming
  • Contents
  • The Importance of Security
  • Securing your PHP Installation
  • User Identification and Authentication
  • Using Cryptography
  • Secure transactions using SSL
  • Installing a Private Key
  • Creating Secure PHP Scripts

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Professional PHP Programming - User Identification and Authentication


    (Page 5 of 9 )

    Every once in a while you will need to uniquely identify a user. Users are usually identified by a challenge and response system. A username/password combination is a good example of such a system, with the challenge being ‘Give me the secret password for Alice’ and the response being Alice’s secret password. This works because user Alice should be the only one who knows the secret password.

    User Authentication by the Web Server
    There is a standard way to authenticate users that requires minimal effort on the side of the PHP programmer. You can simply let Apache take care of authenticating the users.

    AuthName      "Secret page"      # The realm AuthType      Basic   # The password file has been placed outside the web tree AuthUserFile   /home/car2001/website.pw   <LIMIT GET POST> require      valid-user </LIMIT>
    You need to put these directives in a file called .htaccess in the directory you are trying to protect. You also need to create a file with the username/password combinations. You can do this with the htpasswd program that comes with Apache. Storing the password file inside the web tree is a bad idea, so place it somewhere safe outside the web tree and make sure that the permissions on the password file only allow the owner to view and modify the password file. Of course, the web server must be able to read the password file too.

    If you now try to access a file in the protected directory, the web server asks the browser for a username and a password. The browser pops up a small input box where the user can type in their username and password. If the username/password combination matches the values in the password file, the user is allowed to access the page. If not, they get an error page telling them the web server could not authorize them. The realm is shown to the user so that they know which username and password to use.

    The passwords are normally stored in an encrypted form, so even if a malicious user somehow gets their hands on the password file, they still wouldn’t know the passwords. If you know someone got their hands on the password file, you should probably generate new passwords for all the users listed in that file, since it is not impossible, though very hard, for this malicious user to come up with working passwords. That is, if you use passwords that are sufficiently random. The function below generates suitable passwords.

    function randomPassword($length) {    $possible = '0123456789!@#$%^&*()_+' .                'abcdefghjiklmnopqrstuvwxyz' .                'ABCDEFGHIJKLMNOPQRSTUVWXYZ';    $str = "";    while (strlen($str) < $length) {       $str .= substr($possible, (rand() % strlen($possible)), 1);    }    return($str); }
    Don’t forget to initialize the random generator with srand before calling this function or you may be generating the same set of passwords over and over again. It might be a good idea to use mt_rand instead of rand. Not only is mt_rand faster, it is also a better random generator and theoretically generates better passwords. To use mt_rand you need to change one line in the randomPassword function.

    $str .= substr($possible, mt_rand(0, strlen($possible) - 1), 1);
    You could initialize the random generator with something like this (works both for mt_srand and srand):

    mt_srand((double)microtime() * 1000000);
    Apache also supports digest authentication. Digest authentication works just like basic authentication, but the passwords are sent over the Internet in an encrypted form. While this does add security, digest authentication only works with Internet Explorer, which makes it almost impossible to use in most cases. You use htdigest instead of htpasswd to create the password file for digest authentication.
    A small example is shown below.

    <?php   if(!isset($PHP_AUTH_USER)) {     Header("WWW-Authenticate: Basic realm=\"Secret page\"");     Header("HTTP/1.0 401 Unauthorized");     echo "You did not log in correctly...\n";     exit; # exit will stop PHP from parsing the rest of the script   } else {     echo "Hello $PHP_AUTH_USER.<P>";     echo "You entered $PHP_AUTH_PW as your password.<P>";   } ?>
    This can only be seen by someone who has logged in correctly. You can put this piece of code at the top of any page that needs authentication pages. Change the realm if you need different passwords for different sections. You could even have it automatically included in every page with the auto_prepend_file configuration option.

    User Identification and Authentication with PHP
    Doing user authentication in PHP has a lot going for it. It may be a bit more difficult, but the results are worth the extra effort. Below is a list of the many advantages of doing authentication from PHP.
    • It can be undone. A user can “log out”. This is not possible when you let Apache do the authentication.
    • It can expire. You can let logins expire after a certain time. For instance, if someone logged in and did not browse your site for 30 minutes, you could force them to authenticate themselves again.
    • It can be customized. You are only limited by your imagination and your technical skills. You have full control over the complete authentication process. You could for instance, use a small Java applet to send encrypted passwords over the Internet, which could be decrypted on the server with the mcrypt library. This would work with any browser that supports Java.
    • It can be database based. You can use all kinds of data from a database to authenticate users. You could keep a complete logfile of everyone visiting your website. (Note that Apache can get passwords from a database, for instance with the mod_auth_mysql module.)
    • It is per page. You can decide on a per-page basis if you need authentication, which pages are authenticated and which aren't. You can do something similar with Apache by changing the realm, but that is not as flexible.
    • It can be user authenticating and have optional registering. In registration mode, a user without a valid login is encouraged to register and an account is created for this user. The user is able to view the page however, with or without an account.
    • It works with CGI PHP. This is surely a big plus. While letting the webserver do the authentication will work with the CGI version of PHP, your script has no way of finding out who has been authenticated.
    A simple but fully functional example is shown below.

    <? if (!isset($password) || $password != "secret") {    ?>    <FORM ACTION="login.php3" METHOD=POST>    <TABLE><TR><TD><CENTER>    Password: <INPUT NAME=password TYPE=password><BR>    <INPUT TYPE=SUBMIT>    </CENTER></TD></TR></TABLE>    </FORM>    <? } else echo "This is password protected information." ?>
    You can also have the browser display a dialog where the visitor can enter username and password information. This is done with the 401 HTTP status. This example retrieves the username and password combinations from a MySQL database.

    <? if(!isset($PHP_AUTH_USER)) {    Header("WWW-authenticate: basic realm=\"restricted area\"");    Header( "HTTP/1.0 401 Unauthorized");    echo "You failed to provide the correct password...\n";    exit; } else {    mysql_select_db("users");    $user_id = strtolower($PHP_AUTH_USER);    $result = mysql_query("SELECT password FROM users " .                         "WHERE username = '$username'");    $row = mysql_fetch_array($result);    if ($PHP_AUTH_PW != $row["password"]) {      Header( "WWW-authenticate: basic realm=\"restricted area\"");      Header( "HTTP/1.0 401 Unauthorized");      echo "You failed to provide the correct password...\n";      exit;    } } ?>
    Only users with a working username/password combination can see this.


    You could also use a form the let the user input username and password. That way you have complete control over the layout of the HTML pages used.

    Checking IP Addresses
    People often think an IP address uniquely identifies a visitor. Unfortunately, this is not the case. Proxy servers may cause the requests of several visitors to come from the same IP address. If you were to use the IP address of those requests to identify users, you would in fact be checking the IP of the proxy server, which is probably not what you want. For instance, if you have an on-line poll and you allow one vote per IP address, you may only be allowing one vote per ISP. Another problem caused by proxy servers is the fact they may cause the requests from a single visitor to come from several different IP addresses. Multi-user systems and the use of IP masquerading also cause similar problems. This makes the use of an IP address to identify a user troublesome at best.

    IP addresses do have their uses, but they are fairly limited. For instance, if you were running a forum and you were being harassed by a user posting abusive content, you could find out his IP address and ban anyone from that IP address. This is a last ditch method and usually doesn’t work very well. If the he uses a dial-up connection, he could simply reconnect to his ISP and get a new IP. If that ISP had a proxy server, you would be banning everyone who uses that ISP to connect to the Internet.

    The following line will get the IP address that is associated with a particular request.

    $ip = $REMOTE_ADDR;

    ©1998 Wrox Press Limited, US and UK.

    More PHP Articles
    More By Dev Shed


     

       

    PHP ARTICLES

    - Paginating Database Records with the Code Ig...
    - HTTP Headers in Web Development
    - Project Management: Administration
    - Building a Database-Driven Application with ...
    - User Authentication for a Project Management...
    - Introduction to the CodeIgniter PHP Framework
    - Adding Users for a Project Management Applic...
    - Migrating Class Code for a MIME Email to PHP...
    - Login and Logout Authentication for a Projec...
    - Composing Messages in HTML for MIME Email wi...
    - Project Management: Authentication
    - A Better Way to Determine MIME Types for MIM...
    - Project Management Overview
    - Handling Attachments in MIME Email with PHP
    - Completing the Project Management Application





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway