A Simple PHP .htpasswd Manager

Page last updated on 2011 / 04 / 09

Sometimes simplicity is also convenient, and in the case of authentication on the most popular web server, Apache, .htpasswd fits the bill

You may opt for a PHP/MySQL login which in itself is simple enough, but requires the availability of MySQL. If you are on a cheap shared host, MySQL may not be available or is available for a fee.

About .htpasswd

.htpasswd can allow you to authenticate users and restrict access to particular areas of your site. Usernames and passwords are stored in a plain text file with passwords encrypted, while the default setup for Apache 'hides' .htpasswd from direct viewing because the filename begins with a period. To enable .htpasswd, you must declare in .htaccess (or apache2.conf) that a particular directory requires authentication, and indicate what file contains your username and password combinations.

An example .htaccess file indicating that /adminarea/ requires authentication, that should reside in the same folder you require authentication for. Note that the path you reference to the .htpasswd file must be an absolute path:

  1. AuthUserFile /var/www/adminarea/.htpasswd
  2. AuthType Basic
  3. AuthName "Admin"
  4. Require valid-user

And an example .htpasswd file that will reside at /var/www/adminarea/.htpasswd for the purposes of this example

  1. admin:SKuDMdWca/4yk
  2. innvo:CVWMU2otVImPk
  3. michael:JZIuI2F0.uxC.
  4. james:PiECF6UFNQe7s
  5. billg:Zs/QmY/rQHTtI

Managing .htpasswd

Because some shared hosts restrict your available tools and access, it is sometimes helpful to have a PHP script that can manage your .htpasswd file when you are unable to use the command line. If SSH is disabled or command line execution is forbidden, as is often the case on shared hosts, your only other current option is to manage htpasswd via an admin area such as CPanel, which can be slow and inefficient. With this in hand, you may find the following script of interest.

This class will add users, delete users, check if users exists and update existing user's passwords

  1. <?php
  2.  
  3. class htpasswd {
  4. var $fp;
  5. var $filename;
  6.  
  7. function htpasswd($filename) {
  8. @$this->fp = fopen($filename,'r+') or die('Invalid file name');
  9. $this->filename = $filename;
  10. }
  11.  
  12. function user_exists($username) {
  13. rewind($this->fp);
  14. while(!feof($this->fp) && trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp)))))) {
  15. if($lusername == $username)
  16. return 1;
  17. }
  18. return 0;
  19. }
  20.  
  21. function user_add($username,$password) {
  22. if($this->user_exists($username))
  23. return false;
  24. fseek($this->fp,0,SEEK_END);
  25. fwrite($this->fp,$username.':'.crypt($password,substr(str_replace('+','.',base64_encode(pack('N4', mt_rand(),mt_rand(),mt_rand(),mt_rand()))),0,22))."\n");
  26. return true;
  27. }
  28.  
  29. function user_delete($username) {
  30. $data = '';
  31. rewind($this->fp);
  32. while(!feof($this->fp) && trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp))))))
  33. {
  34. if(!trim($line))
  35. break;
  36. if($lusername != $username)
  37. $data .= $line."\n";
  38. }
  39. $this->fp = fopen($this->filename,'w');
  40. fwrite($this->fp,rtrim($data).(trim($data) ? "\n" : ''));
  41. fclose($this->fp);
  42. $this->fp = fopen($this->filename,'r+');
  43. return true;
  44. }
  45.  
  46. function user_update($username,$password) {
  47. rewind($this->fp);
  48. while(!feof($this->fp) && trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp)))))) {
  49. if($lusername == $username) {
  50. fseek($this->fp,(-15 - strlen($username)),SEEK_CUR);
  51. fwrite($this->fp,$username.':'.crypt($password,substr(str_replace('+','.',base64_encode(pack('N4', mt_rand(),mt_rand(),mt_rand(),mt_rand()))),0,22))."\n");
  52. return true;
  53. }
  54. }
  55. return false;
  56. }
  57. }
  58.  
  59. ?>

This gives you some basic examples to work with:

  1. <?php
  2.  
  3. include_once('htpasswd.php');
  4. $htpasswd = new htpasswd('/var/www/adminarea/.htpasswd'); // path to your .htpasswd file
  5.  
  6. // A list of random user names
  7. $users = array('admin','innvo','santa');
  8. // Checking to see which users exist
  9. foreach($users as $user)
  10. echo "The username $user does ".($htpasswd->user_exists($user) ? 'exist' : 'not exist')."\n";
  11.  
  12. // Trying to add all usernames with password 'apples'
  13. foreach($users as $user)
  14. echo "The username $user ".($htpasswd->user_add($user,'apples') ? 'has been added' : 'already exists')."\n";
  15.  
  16. // Trying to remove user 'santa'
  17. echo "Removing user 'santa' if present\n";
  18. $htpasswd->user_delete('santa');
  19. // Trying to update user innvo with new password 'oranges', will add user if they do not exist
  20. if($htpasswd->user_update('innvo','oranges'))
  21. echo "Updated password for 'innvo'\n";
  22.  
  23. ?>

Summary of .htpasswd Class

Before running, ensure you have your .htaccess and .htpasswd files created already, .htpasswd can be left blank.


Previous Article
A Simple PHP Password Generator
Next Article
Creating a Directory Tree with PHP & MySQL (Part 1)




Tweet