Last changes for PHP Login: Access_user Class
Last changed: 2008-01-17
In the past there was only support for PHP’s mail() function to send mail messages. Since some users can't use the mail function because the hosting company doesn't allow this, we decided to implement the phpmailer class as a second option. Now it's possible to send the messages via the mail() function, the sendmail mail program provided by Linux or via SMTP. The two last options are possible with phpmailer class. The phpmailer class is not included. Check the updated send_mail() method and the new constant variables inside the configuration file.
This is an important (security related) update, in previous versions hackers can guess common and repeating passwords from user. While the "forgotten password" function was based on the password and the user id, it could be possible to change the password for some user (if the hacker knows the users id and the right password). The risk is not very high for most installations but could be work out some trouble. The new version doesn't use the password for validation anymore. The login name (encrypted) is used together with some "secret" secret string. AU class user can replace the class file but need to update the method calls in the activate password script. You need to add the constant variable SECRET_STRING to the config file.
There was a small bug inside the constructor method of the user_profile extension, this is fixed now. In previous versions with auto-activation enabled it was possible to activate an account via the activation email after the admin has de-activated an account. The method activate_account() is changed to activate only non-active accounts. The user table need to get updated to use that features (check the SQL statement above the modified method). It's possible now to use a third state "blocked" via the admin panel (the method activation_switch() is modified).
Today a user reported (thanks John Doe 3rd) that for a lot of database queries the class is not safe against SQL injections if magic_quotes_gpc = off. I checked all possible string values and added the function ins_string() to these values. This validation method is not new and was used before for several methods. All users where magic quotes is not configured should update this class or changing the methods where the values entered by the Internet user are send to a database query.
I removed some default variable definitions from the constructor method because sometimes the variables need different values. In previous version you need to define the vars $user and $user_pw with some extra code, in this version they are automatically declared if the session exists. The new argument $redirect inside the constructor is used for the modified method set_user(), this is used to redirect while using the automatic login function. That will say only if the Boolean inside the method is true the redirect will be processed. The test for the existents of the session vars is removed because itâ€™s not necessary anymore. Inside the profile extension is a constructor now, this has the functions from main class constructor and some extra functions make it easier to use the profile extension. Check also the improved example file update_user_profile.php, the complete process is more compact now. To test if there is am existing profile a new example is used "profile_example.php", if there is no profile record the user is redirected to the update profile page (check the new constant variable inside the config file). This feature is useful if the user profile is required inside an application.
In the previous version there was a change to remember an encrypted password and use this value also in the login form. Because the login method needs to accept the raw and the encrypted the password check is less save then in versions before. Because of some complains via the forum I decided to change the cookie bases login process. In this version is the user automatically logged in if a valid cookie exists on the client side. User of this class can disable this feature by setting the variable "save_login" to "no" during the login process. Both login examples are changed and also the methods Access_user(), set_user(), login_reader() and log_out(). Please note also the new created session variable "logged_in", this can be used on pages with conditional content (if a user is logged in or not).
There was a smal bug inside the login_user() method since the last update, a password stored with the cookie doesn't work after teh first logout, this is fixed. Next Sean informed me that inside the access_page() method that there is no exit command after the redirection code. This could be a problem if inside the portected script some code will be executed after the user check. This is fixed and also the logout method got some exit function after the redirection code. If the the sessions are stored inside the MySQL database you need an object free log-out page to remove the session data from the database. Check the logout example and also the new setting for the logout page inside the config file.
There are two important changes in this version: 1. It's possible now to store the session data in your database (this is much safer if you use sessions on a shared hosting server); 2. the password is alsways MD5 encoded now. For the last one there are several methods changed (check the support forum for details, a link is located on the right site of the access_user class website). Further (small) changes: added session_destroy() to the logout method; the links used in the e-mail messages are double md5-encoded now (check the messages with URL's in the messages() method). This is a bigger update, I tried my best to test all changes if something is wrong please let me know (post to the forum).
The variable $access_level is removed, if someone needs the access level value the method get_access_level() must be called. The method returns the access level from a user, the method access_page() is modified to handle this. Inside the example to update the users profile is more example code to show how the different date formats are optimized and processed. The method "create_form_field()" inside the update profile extension is an extra test if a euro-date field is not empty. There was somthing wrong if the class is used to activate the account by admin only. The system was sending the e-mail to the new user. This is fixed inside the register_user() method, rememember to use the variable $auto_activation in the page where the email verification will happen.
Something went wrong during a update in the past, if the autoactivation was set to "false", in this case an e- mail was send without subject and message body. This is fixed inside the method activate_account() on row 376. There was also a small bug inside the update_user_profile example file at row 14, inside the arguments of the function there was an error for the last argument. The variable $send_copy has no function in older versions. If this var is set to "true" after account activation a blind copy is send the site's admin e-mail address.
Until the last version there was a small bug inside the messages method, while sending a confimation the login of the administrator shows up. This wrong login is replaced with the value of the real name field (or a default if this is empty). $msg is changed to get the right (real) name inside the conformation e-mail and also the method send_confirmation() is modified. I added also the missing $msg for several languages. Thank you Dan for your question which points me to this not so gentle bug!
I added two more user fields to the user_profile extension (check also the db_config.php file and update your table). To validate a date to insert/read from the database I changed the method ins_string() from the class source and the profile extension method create_form_field(). The modified ins_string() makes it possible to use an extended string like "some value##date", the string "date" is recognized by this method as the type. Don't forget to validate the input first! Use PHP's date functions like "strftime()" and "strtotime()" for a regular (euro) date output.
There was only one mail subject and message used by different functions, this was not really clear for users. I splitted this messages into new strings, afftected methods: send_mail(), send_confirmation(), forgot_password() and of course the method messages(). I noticed also a bug if the auto_activation is set to true (always the same kind of text). It'f fixed and the register_user() method is changed.
There was a small bug inside the method update_user_by_admin() (file: admin_user.php), I fixed this. Please check the extra information about the database table name convention (inside the documentation file). I added and example how to show the real name in place of the login name inside the file example.php.
There was a small bug if you want to use the class with "auto_activation = false" the method send_mail() is fixed now. Check the new notes inside the help file.
I noticed some conflicts if you use this class together with tables from a different database. I remove the mysql_select_db command and modified the table names (added the database constant). There is a new method (check_new_password()) to check new passwords against a second conformation password. A new message (38) is used if this check result is false. The modified methods register_user() and update_user. The german and french messages are available now in the Users_profile extension. Thank you Francis for the translation job!
There was small bug during the update of a new password via the admin page. It's a BSD style lincense now!
In this version the activation and notivication functions are more optimized. The sendmail() method can handle more different mail jobs and the activate_account() method will use the new method send_confirmation() to inform the user by mail. There are also some inprovements for the user admin function. The class will not send anymore a mail copy to the admin, from now a new mail is send while using the account_activation() method. Notice the new vars inside the db_config file and the modified admin_user.php file.
Find in this version a function to use this class with manual account validation. To handle these requests, a copy of the activation mail mail is to the site admin (new var, check the db_config.php file. The admin_user.php is more extended to handle an activation status update. From the main class the following methodes are changed: send_mail(), activate_account(), messages() and check_email() (optimized regex pattern). Notice the new var inside the login example.
With this version is it finally possible to work with access levels. Find in this distribution all important examples and also a new application file to change the user data (email, password and access level (admin only)). The methods access_page() and register_user()of the main class are modified. Notice the new method get_access_level() and check the db_config.php file for modifications. Thanks, Alex Hayes for helping with the access levels.
There was a small bug inside the get_profile_data() method (profile extension), the phone number was totally ingnored.
I removed the method login_reader() from the constructor because this can create problems if the user have more then one account inside the same application. You have to use this method for now inside the login scripts (they are modified too). I also added booleans to the activate_new_password() method to handle wrong (password) entries. I modified the file "activate_password.php" (new hidden field) to hold the login name after submission of the new password and its possible to check that password is not inserted twice.
some (not so important) bug fixing in the methods: send_mail() and reg_visit(), check_activation_password() (thanks Tomas, for the reports) and forgot_password() (wrong message). In all url's, used by the the method messages() for sending e-mails, is the language available since this version (...&language=$this->language). This will help to indentify the right lang on multilanguage sites.
In older version there is a security problem if someone know the login name from a other user. While using the word "new" as password it was possible to login. This is fixed, I changed the folowing methods: check_user(), login_user() and access_page(). Thanks Mike, for reporting this problem.
If the user change his password and the login data is saved in a cookie before the new password is not updated. I changed this that the cookie is updated too. The update_user() method is changed to handle this.
After reading some stories about SQL injections I checked this class and updated some queries to make more safe: I changed the "type specifier" inside the following methods: check_user(), update_user(), validate_email(), activate_new_password() and inside the profile extension: save_profile_date() and get_profile_data().
I moved the definition of important application files into the config file (see constructor). It's possible to use standard pathes for different uses controlled inside the config file. (modigied methods are Access_user() and messages()). I hope this will make it much easier... At least messages are translated into french, thanks Yoan!
there was a small problem after changing the password in the update_user() method. I moved the md5 encoding a little bit to fix this.
check for all new features the manual for the "Users_profile" extension.
Set the value for this varibales inside the the db_config file: $table_name, $webmaster_mail, $webmaster_name, $cookie_name, $cookie_path. I also removed some (db related) vars from class because there not really needed. The constants are used directly. I remove the post var for the login because there is no need of this (it's a session). I modified the method ins_string() to be more flexible for other types of values (integers).
There was a bug, if one or more users uses the same password. If one of these have forgot the password and uses the forgot password method, than it was possible that the wrong password was updated. The method activate_new_password() is modified to check also the id while updating the password. Inside the check_user() method the "new_pass" case will check the id, the check for active is gone. The method check_activation_password() is changed, too. The activate_password.php file is modified and can handle this new variable. In this version the method for an (updated) e-mail address validation is placed inside the login.php script. This script is used for validation by the e-mail confirmation message.
In older versions the entered login name could be case insensitive, I changed the check_user() method that the entered login name must be case sensitive. I removed the md5 encrypyion for the password in the login_user() method and added the encryption to get_user_info() and update_user() method because there was a problem if you save the login data in a cookie. I added the new is_cookie boolean to the example scripts to switch the login_saver to on/off. If the user saved his data in a cookie before and he unchecked the remember option the cookie will be destroyed. I modified for this functionality the methods login_user(), login_saver() and login_reader().
If a user places the class in the root a bad link was produced while sending a mail (forgot password, register user). After the approvements in In version 1.61 I didn't removed the md5 encoding for the current password. After an update the password was encoded the second time. Both bugs are corrected now.
Changed the md5 encoding to the password in the methods login_user() and get_user_info(), because there was an error reported after updating the account with a new password (the second time). The same time I changed all server variables to fit the configuration with register_globals = off.
The file manual.txt is replaced with a new better manual, access_user_doc.htm. In this file all important functions are described with examples and explanations about how to use the class. Some of the example pages are little bit changed to fit the manual exactly.
I modified the update_user() method to take care of an empty password. If the user doesn't filled the form with a new password the old one will be used during the record update.
The forgot_password() method is complete replaced with some new functions to use a safer way to handle a forgotten password. Check the new / changed methods: check_user(), forgot_password(), check_activation_password(), activate_new_password(), messages(). Find on the example page (forgot_password.php) only the email field. After submitting the form you get an activation link. After clicking this link you can insert a new password. I placed the connect_db() method inside the constructor, too. There is a new appliciation file: activate_password.php, other file(s) are changed (forgot_password.php)
Sinds this release on you have to check for a unique user name too. The following methodes are modified: check_user(), messages(), register_user(). I noticed that after updating an account a double e-mail was not checked in the database. Updates methodes: update_user(), messages(). The login name can't be changed anymore.
I added a function to save the last date of a visit into the extra_info field from the users table. To aktivate this feature you have set the var $count_visit to true.
I modified the "access_page" and "set_user" methods to take care of the "referer" information. With this functions is it possible to remember the address of a page which is requested without login. (see the new example: testpage.php). Notice the new methods "login_saver" and "login_reader". With this functions is it possible to remember the login information on the client side.
Now it is possible to update an account, use the new example page (update_user.php). While updating the class I changed the structure of method's which are called from outside the class. In this version the vars are given to the method and not more predefined. If some one want to update this class for PHP 5 than its possible to separate private vars. Several methods are more flexible than before and I removed some small bugs.
added new property: language, together with the new error reporting method is it possible to translate the messages. Im removed the properties $ok_msg and $error_msg, use for now only (the new one) $the_msg.
new method: get_user_info(), use this to retrieve all user date from the database (to show the visitor his information).
Added the db_config.php file with some constants for the database connection, this makes the whole more flexible.
Back to the PHP class: PHP Login: Access_user Class