Rewrite htaccess rules not working perfect

I have a bunch of rules for different categories, here is one category...

RewriteRule ^words/$ /words/publicWordLists.php [L]
RewriteRule ^words/([A-Za-z]+$) /words/word.php?word=$1 [L]
RewriteRule ^([A-Za-z0-9-]+)/words/$ /words/userWordLists.php?username=$1 [L]
RewriteRule ^([A-Za-z0-9-]+)/words/([A-Za-z0-9-]+$) /words/list.php?username=$1&url=$2 [L]

This works great in that if you go to words/ you get the content from publicWordsList.php - HOWEVER - if you go to directly to /words/publicWordLists.php - it doesn't redirect back to words/

So how do I prevent people from directly accessing those pages while still maintaining my initial intentions?

1 answer

  • answered 2018-11-08 23:37 MrWhite

    You can create a "redirect" at the top of the file that 301 redirects from the "ugly" filesystem path to the desired URL. However, you need to be careful of redirect loops, since the later rewrite rewrites the URL back again.

    For example:

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^words/publicWordLists\.php$ /words/ [R=302,L]
    

    The check against the environment variable REDIRECT_STATUS prevents a redirect loop as it only looks at the initial request, not the rewritten request. REDIRECT_STATUS is empty initially, but set to "200" after the first successful rewrite.

    Change 302 (temporary) to 301 (permanent) only once you have confirmed everything works OK - to avoid potential caching issues.

    Your other directives that contain a query string are a little more tricky as they require an additional condition. The query string is not part of the URL-path that is matched by the RewriteRule pattern.

    For example:

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteCond %{QUERY_STRING} ^word=([a-zA-Z]+)$
    RewriteRule ^words/word\.php$ /words/%1 [QSD,R=302,L]
    

    The above redirects /word/word.php?word=<something> to /words/<something>.

    %1 is a backreference to the URL parameter value captured in the preceding RewriteCond directive. The QSD flag is necessary to remove the original query string from the redirected request.