Showing posts with label Apache. Show all posts
Showing posts with label Apache. Show all posts

Friday, June 25, 2010

PHP Session Issues

I recently had a ridiculous problem with a user authentication script on a site I was making. Upon first loading the page, a user would have to execute the login script twice for the account to be authenticated. It literally puzzled me for weeks.

Eventually, I had determined that there was something about the PHP session variables that was not being set. I had no other problems elsewhere I employed PHP sessions; just the login script. Further investigation revealed that the real issue was with the cookie the PHP session creates.


Important Note: When session_start() is called, a cookie is created and the session id is stored in it. For more on PHP sessions, check out this article from php.net. 


Here is how it breaks down:

  1. The user points their browser to http://url.com/index.php
  2. The user attempts to log into the site.
  3. The authentication script calls session_start() and logs the user in, setting a state variable $is_logged_in to true.
  4. When the script ends, it redirects the user to a page using header('Location: http://www.url.com/somepage.php').
  5. The $is_logged_in = true in the PHP session does not carry over from the authentication script.
Why?

The PHP session data cannot be accessed by somepage.php because when the authentication script called session_start(), a cookie (learn more about PHP and cookies) was created and assigned to the "http://url.com". When the redirect completes, the current domain is now "http://www.url.com". It is a simple mistake, but devastatingly annoying.

Solution 1: Using a PHP Configuration File

There are a number of ways to remedy this issue. I chose a preventative approach which requires an .htaccess file. 

If you have access to (check with your hosting provider if you are unsure) your PHP Configuration File, php.ini, you can add a directive that forces PHP to always issue cookies to the top-level domain and all subdomains. Add the following line to your php.ini file: 

session.cookie_domain = .url.com 

For more information, read this. Please note the period before the "url.com". It is important. Also, note the lack of single or double quotation marks.

Solution 2: Inline Directive

Instead of having to modify your php.ini file, you can set the cookie domain inline with a particular script using the ini_set() function (see PHP manual). Add the following line to your PHP script: ini_set('session.cookie_domain', '.url.com'); Take note again of the period before "url.com".

Solution 3: .htaccess RewriteRule

This is the method I chose because it is an inherently proactive approach. It requires an .htaccess file and the following code:

Options +FollowSymlinks
RewriteEngine on

RewriteCond %{HTTP_HOST} ^url.com [NC]
RewriteRule ^(.*)$ http://www.url.com/$1 [L,R=301]

The first line tells Apache to honor symbolic file links. If you have a file symbolically linked to another file and get a HTTP 403: Forbidden when trying to access it, it may be because your .htaccess file lacks this line. The second line tells Apache to enable URL rewriting (see Apache manual). This is the first step to fixing the matter at hand. The third line is a rewrite condition (see Apache manual). If the condition is met, it executes the following rewrite command on the fourth line. The RewriteCond condition verifies that the base domain is exactly url.com. If the condition is met, line four takes the URI and appends it to the string "http://www.url.com/", forcing the www subdomain. 

Problem solved.

Sunday, June 13, 2010

Creating Vanity URLs with .htaccess

I had to do this for a project website I was working on recently. We knew we wanted the user's profile to be accesible by entering the www.url.com/username. This was, more or less, created automatically when the user created a profile. I brainstormed dozens of ideas, all of which were either not secure or overly complicated. Finally, the answer came to me: .htaccess and regular expressions.

Our server is Linux-based and runs Apache for the web server. Because we use Apache, we can use .htaccess...and it is a beautiful thing.

An .htaccess file is used for a number of reasons:

1. To redirect a user to File B when they try to access File A
2. Restrict/allow access to particular directories or files (with a little help from .htpasswd)
3. To beautify long, cryptic URLs

The way in which .htaccess accomplishes #3 is via mod_rewrite. Here us some more information regarding this Apache module. To enable mod_rewrite, add the following two lines to .htaccess file:


Options +FollowSymlinks
RewriteEngine on

For the sake of example, let us say that the PHP file that handles displaying a users profile is named profile.php. Furthermore, a username may be comprised of numbers, letters (upper and lower case), periods, hyphens and underscores. Adding the following rule:

RewriteRule ^([A-Za-z0-9\._\-]+)+[^\.php]$ profile.php?&uri=$0 [NC]

 to the .htaccess file will rewrite http://www.url.com/username to http://www.url.com/profile.php?uri=username. An important note about the rewrite is that http://www.url.com/username is what is still displayed in the browser's address bar. Thus, a vanity URL!

An explanation of the regular expression used in the rule is beyond the scope of this post. Read more about using regular expressions with mod_rewrite.