Force https for some pages and http for all others

2019-08-04 19:11发布

问题:

In .htaccess (Apache 2.4.6) file i do this:

RewriteCond %{HTTPS} =off [NC]
RewriteCond %{REQUEST_URI} ^\/(login|checkout)\/?(.*) [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

So, if my user get in http://site/login he is redirected to https://site/login. The same for checkout page.

But, for all others pages i do not want allow access to https protocol. In this cases i want force 301 redirect to http protocol.

For example: If my user access https://site/products i need it redirect him to http://site/products.

So, i added a new RewriteCond negating the regex, like this:

RewriteCond %{HTTPS} =on [NC]
RewriteCond %{REQUEST_URI} ^\/((?!login|checkout))\/?(.*) [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

But it didn't work.

Any ideas for this problem? Tks.

My .htaccess file

Options +FollowSymLinks -MultiViews
DirectoryIndex index.php

RewriteEngine On

# Force HTTP to HTTPS
RewriteCond %{HTTPS} =off [NC]
RewriteCond %{REQUEST_URI} ^/index.php/(login|checkout) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# Force HTTPS to HTTP
RewriteCond %{HTTPS} =on [NC]
RewriteCond %{REQUEST_URI} !^/index.php/(login|checkout) [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# From /index.php/ to /
RewriteCond %{THE_REQUEST} ^.*/index.php 
RewriteRule ^(.*)index.php/?$ /$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

The first rule, if my user get in on /index.php/login he is redirected to /login, removing the /index.php/ from URI.

The last rule delegate all calls to index.php for request dispatch (front controller).

回答1:

Your negative lookahead doesn't seem to be correct.

And you can negate earlier URI matching condition in a simpler syntax also. So overall these 2 rules should work:

Options +FollowSymLinks -MultiViews
DirectoryIndex index.php

RewriteEngine On

# Force HTTP to HTTPS
RewriteCond %{HTTPS} =off [NC]
RewriteCond %{THE_REQUEST} /(login|checkout) [NC]
RewriteRule ^(login|checkout) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# Force HTTPS to HTTP
RewriteCond %{HTTPS} =on [NC]
RewriteCond %{THE_REQUEST} !/(login|checkout) [NC]
RewriteRule !^(login|checkout) http://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]

# From /index.php/ to /
RewriteCond %{THE_REQUEST} ^.*/index.php 
RewriteRule ^(.*)index.php/?$ /$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Delegate all requests to the index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [L]