Search code examples
.htaccess

htaccess block original file however allow rewrite


I have the following entries in my /.htaccess

RewriteEngine On
RewriteBase /

RewriteRule ^signin.php - [L,gone]
RewriteRule ^sign-in/?$  /signin.php [L]

What I am trying to achieve is to allow the user to access /sign-in but not the original file /signin.php

I saw this other question however when I tried to implement the answer I get gone error on both /sign-in and /signin.php.

Referenced Question: Alias within htaccess, and block access to original file? (URL rewriting)

Thanks for any help.


Solution

  • To redirect any direct requests for /signin.php to /sign-in and internally rewrite /sign-in back to /signin.php then you can do it like this:

    RewriteEngine On
    
    RewriteRule ^signin\.php$ /sign-in [R=301,L]
    RewriteRule ^sign-in$ signin.php [END]
    

    The END flag (Apache 2.4) prevents any further loops by the rewrite engine, so prevents the rewritten URL being redirected back to /sign-in, which would otherwise cause a redirect loop.

    The END flag is not required on the first rule, since an external redirect will trigger immediately. (The L flag is still required.)

    You do not need the RewriteBase directive here.

    I removed the optional trailing slash on /sign-in as this potentially creates a duplicate content issue. If you wish to allow an optional trailing slash then redirect to the canonical URL (without the trailing slash, or with if you prefer) instead.


    UPDATE:

    I saw this other question however when I tried to implement the answer I get gone error on both /sign-in and /signin.php.

    Referenced Question: Alias within htaccess, and block access to original file? (URL rewriting)

    The Apache solution in the referenced answer is not quite correct. The answer would seem to have been "accepted" for the first part regarding doing this in PHP instead.

    At the time of that question (2011), they would have been using Apache 2.2. The END flag was only introduced in Apache 2.4.

    They would have needed to have done it like this, to prevent a redirect loop:

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^about.php /about [L,R=301]
    
    RewriteRule ^about$ about.php [L]