views:

838

answers:

5

In my .htaccess file I have defined the following rule to make my register page URL as http://example.com/register/

RewriteRule register/ /register.php

The above rule is perfectly fine but I can access my register page from http://example.com/register/ as well as from http://example.com/register.php.

I don't want that user will be able to access the URL from http://example.com/register.php URL, is there any RULE which I can define in .htaccess to stop execution of register.php URL or simply redirect any direct register.php request to /register/

+3  A: 

If you are doing this to avoid getting multiple links to the same content, you can simply don't use "register.php" anywhere on your page. I think no search engine will "guess" for a certain file type and if there are no security concerns you are on the safe side, because in my opinion no user will link to this file either. However if you want to be certain just reroute all your functionality through an index.php via one line in your .htaccess which should be placed inside your www-root directory:

RewriteEngine on
RewriteRule ^(.*?)$ index.php?file=$1

In your index.php you can then simply choose which function/file to invoke by breaking down and checking the $_GET["file"] parameter. To make 100% certain no one can access your register.php file directly just move it (and all your others) to a separate directory and include a .htaccess file with the following line:

DENY from all

There are a couple of other options to prevent direct access. Just define() a variable somewhere in your index.php and at the top of your register.php just put

defined('access') or die('Intruder alert!');

at the top. Another way could be to be honest and simply tell search engines that your content has been moved and that they no longer should use the old link:

header("Status: 301"); /* Content moved permanently */
header("Location: http://yourserver/Register/");
exit;

Update

Just one more thing that crossed my mind, you can also check $_SERVER["REQUEST_URI"], whether the user attached any ".php" and act accordingly by either denying access completely or just redirecting to the new location.

merkuro
This is the approach many frameworks take to create readable URIs. +1
Boldewyn
A: 

Try this.

RewriteCond %{REQUEST_FILENAME} ^register\.php$ [NC]
RewriteRule ^/register register.php

Or this

Redirect register.php /register
SleepyCod
The problem with the second rule is, that, combined with the one in the question it creates an infinite loop.
Boldewyn
A: 

Ignoring the user-experience part, you can implement the new rel=canonical link to sort out the search engines.

Although, for this case you should probably just use a 301 redirect from /register.php to /register/

In register.php

if ( stristr( $_SERVER['REQUEST_URI'], '.php' ) )
{
    header ('HTTP/1.1 301 Moved Permanently');
    header ('Location: /register');
}
Peter Bailey
Use `$_SERVER['REQUEST_URI']`. The SCRIPT_NAME is essentially identical to __FILE__, and hence the test yields always true.
Boldewyn
darn da backticks... `__file__` I meant.
Boldewyn
oh yeah, sorry. Fixed it to use the right value.
Peter Bailey
A: 

If you want to completely block /register.php by using mod_rewrite, use a variant of SleepyCod's answer:

RewriteCond %{REQUEST_FILENAME} register\.php [NC]
RewriteCond %{IS_SUBREQ} false
RewriteRule .* - [F,L]

Explanation:

  • [NC]: Makes the condition case-insensitive, just in case you're on a windows box.
  • Condition 1: The requested filename is 'register.php', and
  • Condition 2: The request is no subrequest (this is important, since every new round through RewriteRules actually creates subrequests).
  • Rule: essentially do nothing
  • Flags: [F]: Send an 403 Forbidden header, [L]: This is the last rule to apply, skip all following rewrite rules

Rewriting correctly is an art by itself. I suggest you carefully read http://httpd.apache.org/docs/2.2/rewrite/.

Cheers,

Boldewyn
I think that you forgot the [NC] flag in there somewhere!
a_m0d
yes, indeed, thanks!
Boldewyn
A: 

To check the initial requested URL path, you need to use the request line. So try this rule:

RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php[/?\s]
RewriteRule (.+)\.php$ /$1 [L,R=301]

And then again your rule (in a slightly modified way):

RewriteRule ^register/$ register.php
Gumbo