Skip to content
Advertisement

.htaccess redirect /subpage/ to /subpage?/wp-login

Trying to use .htaccess rule to do the wp-login JS check on first visit by appending ?/wp-login to the url since it’s interferring with Sucuri firewall when using password protection.

I’ve created a test subdomain to try to get the htaccess redirect to work before using it on the live site:

RewriteCond %{QUERY_STRING} ^protectedpage$
RewriteRule ^(.*)$ https://testing.no11.ee/protectedpage?/wp-login [R=302,L]

view here: testing.no11.ee/protectedpage

Unfortunately this does not add the query arg to the url. What am I doing wrong here? Expected result when visiting page should be https://testing.no11.ee/protectedpage?/wp-login as the browser url.

Full htaccess:

# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{QUERY_STRING} ^protectedpage$
RewriteRule ^(.*)$ https://testing.no11.ee/protectedpage?/wp-login [R=302,L]
</IfModule>
# END WordPress

Advertisement

Answer

RewriteCond %{QUERY_STRING} ^protectedpage$
RewriteRule ^(.*)$ https://testing.no11.ee/protectedpage?/wp-login [R=302,L]

This checks that the QUERY_STRING is set to protectedpage, but in your example it’s the URL-path that is /protectedpage, not the query string.

You also need to first check that the query string is not already set to /wp-login, otherwise you’ll get a redirect loop.

However, you’ve also put the code in the wrong place. Note the WordPress comment that precedes the code block – you should not manually edit this code. This directive also needs to go before the WordPress front-controller, otherwise, it’s simply never going to get processed.

Try the following instead before the # BEGIN WordPress comment marker:

RewriteCond %{QUERY_STRING} !^/wp-login$
RewriteRule ^(protectedpage)/?$ /$1/?/wp-login [R=302,L]

This matches an optional trailing slash on the requested URL, but it redirects to include the trailing slash in the target URL.

(You do not need to repeat the RewriteEngine on directive.)

No need to include the scheme + hostname if you are redirecting to the same. The $1 backreference simply saves repetition and refers to the matched URL-path, ie. protectedpage (without the trailing slash) in this example.

However, this always redirects and appends /wp-login to this URL – not just the “first visit” – is that really what you require? Otherwise, you need to somehow differentiate between “first” and “subsequent” visits (by detecting a cookie perhaps?)

UPDATE: Minor addition: how would one improve this to add ?/wp-login to all urls that have the page /subpage/ as parent i.e /subpage/page-1 and /subpage/page-2 would result in /subpage/page-1?/wp-login etc? I tried using (.*) but this delets the subpage from the url…

You could do something like the following:

RewriteCond %{QUERY_STRING} !^/wp-login$
RewriteRule ^(subpage/[^/]+)/?$ /$1/?/wp-login [R=302,L]

The [^/]+ subpattern matches any character except / – so only the second path segment, excluding the optional trailing slash. This is similar to .*, but this would capture everything, including any trailing slash, so would result in a double slash in the redirected URL.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement