Related
I'm trying to redirect all insecure HTTP requests on my site (e.g. http://www.example.com) to HTTPS (https://www.example.com). How can I do this in .htaccess file?
By the way, I'm using PHP.
The Apache docs recommend against using a rewrite:
To redirect http URLs to https, do the following:
<VirtualHost *:80>
ServerName www.example.com
Redirect / https://www.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
This snippet should go into main server configuration file, not into .htaccess as asked in the question.
This article might have come up only after the question was asked and answered, but seems to be the current way to go.
Update: Although this answer has been accepted a few years ago, note that its approach is now recommended against by the Apache documentation. Use a Redirect instead. See this answer.
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
I'd recommend with 301 redirect:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
As I was saying in this question, I'd suggest you avoid redirecting all HTTP requests to their HTTPS equivalent blindly, as it may cause you a false impression of security. Instead, you should probably redirect the "root" of your HTTP site to the root of your HTTPS site and link from there, only to HTTPS.
The problem is that if some link or form on the HTTPS site makes the client send a request to the HTTP site, its content will be visible, before the redirection.
For example, if one of your pages served over HTTPS has a form that says <form action="http://example.com/doSomething"> and sends some data that shouldn't be sent in clear, the browser will first send the full request (including entity, if it's a POST) to the HTTP site first. The redirection will be sent immediately to the browser and, since a large number of users disable or ignore the warnings, it's likely to be ignored.
Of course, the mistake of providing the links that should be to the HTTPS site but that end up being for the HTTP site may cause problems as soon as you get something listening on the HTTP port on the same IP address as your HTTPS site. However, I think keeping the two sites as a "mirror" only increases the chances of making mistakes, as you may tend to make the assumption that it will auto-correct itself by redirecting the user to HTTPS, whereas it's often too late. (There were similar discussions in this question.)
This is the html redirect approach it works but not the best.
<meta http-equiv="Refresh" content="0;URL=https://www.example.com" />
PHP approach
<?php
function redirectTohttps() {
if ($_SERVER['HTTPS']!="on") {
$redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("Location:$redirect");
}
}
?>
.htaccess approch
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
copied from:
www.letuslook.org
I found out that the best way for https and www on domain is
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
I like this method of redirecting from http to https. Because I don't need to edit it for each site.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Using the following code in your .htaccess file automatically redirects visitors to the HTTPS version of your site:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you have an existing .htaccess file:
Do not duplicate RewriteEngine On.
Make sure the lines beginning RewriteCond and RewriteRule immediately follow the already-existing RewriteEngine On.
The best solution depends on your requirements. This is a summary of previously posted answers with some context added.
If you work with the Apache web server and can change its configuration, follow the Apache documentation:
<VirtualHost *:80>
ServerName www.example.com
Redirect "/" "https://www.example.com/"
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
But you also asked if you can do it in a .htaccess file. In that case you can use Apache's RewriteEngine:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
If everything is working fine and you want browsers to remember this redirect, you can declare it as permanent by changing the last line to:
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
But be careful if you may change your mind on this redirect. Browsers remember it for a very long time and won't check if it changed.
You may not need the first line RewriteEngine On depending on the webserver configuration.
If you look for a PHP solution, look at the $_SERVER array and the header function:
if (!$_SERVER['HTTPS']) {
header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
}
This is the proper method of redirecting HTTP to HTTPS using .htaccess according to GoDaddy.com. The first line of code is self-explanatory. The second line of code checks to see if HTTPS is off, and if so it redirects HTTP to HTTPS by running the third line of code, otherwise the third line of code is ignored.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
https://www.godaddy.com/help/redirect-http-to-https-automatically-8828
Add the following code to the .htaccess file:
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^ https://[your domain name]%{REQUEST_URI} [R,L]
Where [your domain name] is your website's domain name.
You can also redirect specific folders off of your domain name by replacing the last line of the code above with:
RewriteRule ^ https://[your domain name]/[directory name]%{REQUEST_URI} [R,L]
Do everything that is explained above for redirection. Just add "HTTP Strict Transport Security" to your header. This will avoid man in the middle attack.
Edit your apache configuration file (/etc/apache2/sites-enabled/website.conf and /etc/apache2/httpd.conf for example) and add the following to your VirtualHost:
# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so
<VirtualHost 67.89.123.45:443>
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>
https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
To redirect all http requests to https , you can use :
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]
If mod-rewrite isn't enabled and you are on apache 2.4, you can also use a Redirect inside if directive to redirect http requests to https .
Apache 2.4.
<if "%{HTTPS} !~ /on/">
Redirect / https://www.example.com/
</if>
If you are in a situation where your cannot access the apache config directly for your site, which many hosted platforms are still restricted in this fashion, then I would actually recommend a two-step approach. The reason why Apache themselves document that you should use their configuration options first and foremost over the mod_rewrite for HTTP to HTTPS.
First, as mentioned above, you would setup your .htaccess mod_rewrite rule(s):
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Then, in your PHP file(s) (you need to do this where ever it would be appropriate for your situation, some sites will funnel all requests through a single PHP file, others serve various pages depending on their needs and the request being made):
<?php if ($_SERVER['HTTPS'] != 'on') { exit(1); } ?>
The above needs to run BEFORE any code that could potentially expose secure data in an unsecured environment. Thus your site uses automatic redirection via HTACCESS and mod_rewrite, while your script(s) ensure no output is provided when not accessed through HTTPS.
I guess most people don't think like this, and thus Apache recommends that you don't use this method where possible. However, it just takes an extra check on the development end to ensure your user's data is secure. Hopefully this helps someone else who might have to look into using non-recommended methods due to restrictions on our hosting services end.
Unless you need mod_rewrite for other things, using Apache core IF directive is cleaner & faster:
<If "%{HTTPS} == 'off'">
Redirect permanent / https://yoursite.com/
</If>
You can add more conditions to the IF directive, such as ensure a single canonical domain without the www prefix:
<If "req('Host') != 'myonetruesite.com' || %{HTTPS} == 'off'">
Redirect permanent / https://myonetruesite.com/
</If>
There's a lot of familiarity inertia in using mod_rewrite for everything, but see if this works for you.
More info: https://httpd.apache.org/docs/2.4/mod/core.html#if
To see it in action (try without www. or https://, or with .net instead of .com): https://nohodental.com/ (a site I'm working on).
Redirect 301 / https://example.com/
(worked for me when none of the above answers worked)
Bonus:
ServerAlias www.example.com example.com
(fixed https://www.example.com not found)
take this code to you .htaccess file
Redirect HTTP to HTTPS automatically
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The above things are for the Apache server only. What if running PHP at tomcat?
So you can use PHP code, whether it is Apache/tomcat/Nginx etc...
if (!((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))){
$redirect = 'https://' . str_replace($_SERVER['SERVER_PORT'], 8443, $_SERVER['HTTP_HOST']) . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
}
After lots of tries by considering without www and with www this works this
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} (www\.)?yourdomain.com
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Through .htaccess This will help.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
Also, Refer this for More Detail. How To Redirect Http To Https?
I found a method to force all pages of my site redirect from http to analog of pages on https that work for me.
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
This redirects all the URLs to https and www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
If you want to do it from the tomcat server follow the below steps
In a standalone Apache Tomcat (8.5.x) HTTP Server, how can configure it so if a user types www.domain.com, they will be automatically forwarded to https(www.domain.com) site.
The 2 step method of including the following in your [Tomcat_base]/conf/web.xml before the closing tag
step 1:
<security-constraint>
<web-resource-collection>
<web-resource-name>HTTPSOnly</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
and setting the [Tomcat_base]/conf/server.xml connector settings:
step 2:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="443"/>
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="[keystorelocation]" type="RSA" />
</SSLHostConfig>
</Connector>
Note: If you already did the https configuration and trying to redirect do step 1 only.
Not only can you do this in your .htaccess file, you should be doing this period. You will also want to follow the steps here to get your site listed on the HSTS preload list after you implement this redirect so that any requests to the insecure http version of your website never make it past the user agent. Instead, the user agent checks the requested URI against a baked in list of https only websites and, if the requested URI is on that list, changes the protocol from http to https before transmitting the request to the server. Therefore, the insecure request never makes it out into the wild and never hits the server. Eventually when the internet changes over to https only the HSTS preload list will not be needed. Until then, every site should be using it.
In order to perform the redirect, we need to enable the rewrite engine and then redirect all traffic from the http port 80 to https.
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://yourwebsite.tld/$1 [L,R=301]
I tried all .htaccess configurations I could find on the internet but none worked.
Then, I realized Apache discourages using mod_rewrite.
My solution was to edit apache configuration files under the following folder:
/etc/apache2/sites-enabled
You will have one mandatory file named 000-default.conf and an ssl configuration file named 000-default-le-ssl.conf (if you have installed ssl certificate from letsencrypt/certbot). However, these files can be named differently depending on the file names you provided when setting up the site.
In 000-default.conf, I edited the following inside <VirtualHost *:80> as:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
In 000-default-le-ssl.conf, I edited the following inside <VirtualHost *:80> as:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
No other redirection is needed.
Save the file then restart the apache server using sudo service apache2 restart
I was actually trying to get this to work on an EC2 instance without a load balancer since that costs money. I've read everywhere that .htaccess isn't the "right" way to do it. Obviously, it will work, but I was trying to keep things by the book. I was following all of the examples to update the httpd.conf file and adding a lot of unnecessary stuff. It turns out the only line you really need is this:
Redirect permanent / https://www.yourdomain.com
My problem was that originally I had added this in a VirtualHost tag inside of httpd.conf, which is what a lot of posts tell you to do, but it wasn't working. It turns out there was a separate conf file stored in /etc/httpd/conf.d called yourdomain.conf which already had the VirtualHost tag and was overriding my httpd.conf settings. I just added the above line inside of it and voila, it instantly redirected to https. There is no need for the separate VirtualHost for port 443.
It's working now and the VirtualHost tag looks like this:
<VirtualHost *:80>
ServerName yourdomain.com
DocumentRoot /var/www/html
ServerAlias www.yourdomain.com
ErrorLog /var/www/error.log
CustomLog /var/www/requests.log combined
Redirect permanent / https://www.yourdomain.com
</VirtualHost>
Note: I already had TLS setup with a FREE certificate from certbot (Love those guys) and was just trying to redirect regular http calls to the working https site.
If you are using Apache, mod_rewrite is the easiest solution, and has a lot of documentation online how to do that. For example: http://www.askapache.com/htaccess/http-https-rewriterule-redirect.html
A different edge to this problem is when a Load Balancer comes into play.
The situation is as follows:
- Traffic from browser to Load Balancer, and back, is (should be) HTTPS
- Traffic between Load Balancer and actual WebServer is HTTP.
So, all server request variables in PHP or Apache show that the connection is just HTTP. And the HTTP and HTTPS directories on the Server are the same.
The RewriteCondition in the approved answer does not work.
It gives either a loop or it just doesn't work.
Question is: How to get this working on a Load Balancer.
(Or is the Load Balancer configured wrong. Which is what I'm hoping for because then I can move the problem over to the WebHosting company :-) )
If you're using an Amazon Web Services Elastic Load Balancer which accepts https traffic and routes it to your server(s) with http, the correct way to redirect all http traffic to https is described here: https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb
Use the X-Forwarded-Proto header (contains http or https) which is always included in http requests from the load balancer, as described here: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
In the httpd.conf file:
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
</VirtualHost>
Or in your root .htaccess file:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
Bonus: it will not try to redirect http traffic on your local development machine.
It works for me:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
and for example, http://server/foo?email=someone%40example.com redirects normally without any issues.
The file .htaccess located in the website root folder (for example named public_html).
It is possible to use
RewriteCond %{SERVER_PORT} !^443$ instead RewriteCond %{HTTPS} !on
Trying to get
www.example.com/admin
and allow ip x.x.x.x
if not this ip (x.x.x.x)to go directly to
www.example.com/
#/vhdocs/example/web/docroot/application/controllers/admin
What I've tried:
RewriteEngine on
RewriteBase /
# RewriteCond %{HTTP_REFERER} ^http://example.com/admin$
# RewriteCond %{REMOTE_ADDR} !^x\.x\.x\.x$
# RewriteRule ^/* http://www.example.com [L]
What am I doing wrong?
Mostly correct, but too complicated. Try this instead:
RewriteEngine on
RewriteBase /
RewriteCond %{REMOTE_ADDR} !^x\.x\.x\.x$
RewriteRule ^/?admin$ http://www.example.com [L,R=301]
This version should work both in .htaccess style files and in the http servers host configuration. Note that you should only use .htaccess style files if you really have no other choice. Those files are notoriously error prone, hard to debug and they really slow down the server, often for nothing. They are only provided as a last option for those who do not have access to the host configuration and who cannot implement such logic in a routing script.
I am working on a Drupal site for which the client has requested that we remove the 'www.' from the URL. This is super easy and I've done it before; I simply comment out the suggested lines in the Drupal-generated .htaccess file like so:
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment the following:
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
Those of you familiar with Drupal's .htaccess will know that the environment variable protossl is set towards the top of the file like so:
# Set "protossl" to "s" if we were accessed via https://. This is used later
# if you enable "www." stripping or enforcement, in order to ensure that
# you don't bounce between http and https.
RewriteRule ^ - [E=protossl]
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=protossl:s]
This is working perfectly on my local environment, but when I deployed the change to the production site it breaks. www.mysite.com redirects to mysite.com as expected, but https://www.mysite.com also redirects to mysite.com instead of https://mysite.com. It seems that the %{HTTPS} variable is returning 'off' even when it should be 'on'.
I can go directly to https://mysite.com and it works perfectly. The site's Apache access logs show 'https://' where I expect it to be, as do all of my HTTP requests. The site is running on a RackSpace server using a load balancer (only one node in the balancer). The SSL certificate is on the RackSpace load balancer. I have tried the following steps and none have had any results:
Replace RewriteCond with RewriteCond %{ENV:HTTPS} on [NC]
Replace RewriteCond with RewriteCond %{SERVER_PORT} ^443$
Multiple variations and combinations of the above RewriteCond's
Added $conf['https'] = TRUE; to settings.php
This is driving my coworkers and I crazy. Can anyone help?
anubhava has saved the day! The solution was to use the %{HTTP:X-Forwarded-Proto} variable just as he suggested. I updated the protocol detection bit of my .htaccess to look like this:
# Set "protossl" to "s" if we were accessed via https://. This is used later
# if you enable "www." stripping or enforcement, in order to ensure that
# you don't bounce between http and https.
RewriteRule ^ - [E=protossl]
# The default proto detection provided by Drupal does not work on our
# production server because it sits behind a load-balancing server.
# This additional RewriteCond makes sure we can detect the forwarded proto
RewriteCond %{HTTP:X-Forwarded-Proto} https [OR]
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=protossl:s]
I'm gonna call this a crunchwrap supreme, 'cause it is good to go!
I am having some issues setting up my htaccess to allow multiple languages utilising the sub directory method eg:
http://www.domain.com/en/
http://www.domain.com/sw/
http://www.domain.com/ie/
Also to complicate things, the project isn't currently live, its on a dev server. For example, I am currently accessing the project at:
http://dev.domain.com/devname/projectname/
And I want the above to automatically 301 redirect to:
http://dev.domain.com/devname/projectname/en/
Here is my htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# ----------------------------------------------------------------------
# MULTI LANGUAGE SUB DIRECTORY
# ----------------------------------------------------------------------
RewriteCond %{REQUEST_URI} !^/(en|sw)/
RewriteRule ^(.*)$ en/$1 [R=301,L]
# ----------------------------------------------------------------------
# Rewrite rules
# ----------------------------------------------------------------------
## CASE STUDIES ##
RewriteRule ^casestudies/([^/\.]+).html$ index.php?controller=contents&method=viewCasestudy&link=$1 [L,QSA]
## PRODUCTS ##
RewriteRule ^products/([^/\.]+).html$ index.php?controller=contents&method=viewProduct&link=$1 [L,QSA]
RewriteRule ^([a-z{2}]+)(/)?$ index.php?controller=contents&method=viewHome&lang=$1 [L,QSA] # Default load
RewriteRule ^(/)?$ index.php?controller=contents&method=viewHome [L,QSA] # Default load
The above will actually redirect to:
http://dev.domain.com/home/webserver_dir/devname/projectname/en/
..and if I use RewriteBase it seems to just goto...
http://dev.domain.com/en/
So my question: How do I get the language URLs working correctly relative to the directory its in on my dev server, and then ideally will work when it goes live without any environment specific rules.
Bonus question: Do I need to add the ([a-z{2}]+) bit in front of all my subsequent rewrite rules or can I have a catch all that will effect all further rules?
EDIT -----------------------------
I have reduced it down to the following as suggested...
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /devname/projectname/
RewriteCond %{REQUEST_URI} !^/(en|sw)(/|$) [NC]
RewriteRule ^(.*)$ en/$1 [R=301,L]
RewriteRule ^([a-z]{2})/?$ index.php?controller=contents&method=viewHome&lang=$1 [NC,L,QSA] # Default load
... but now its redirecting to http://dev.domain.com/devname/projectname/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/, any ideas?
Have you tried the answer in the following link? It should do what you're trying to achieve.
Endless Redirect Loop by htaccess rules multi language
RewriteEngine On
RewriteBase /
# empty url -> redirect to en/
RewriteCond %{QUERY_STRING} !lang=(en|de)
RewriteRule ^$ en/ [R=301,L]
# url is ONLY '/en' or '/de' -> redirect to /en/ or /de/ (adding slash)
RewriteRule ^(en|de)$ $1/ [R=301,L]
# now all urls have en/ de/ -> parse them
RewriteRule ^(en|de)/(.*)$ $2?lang=$1&%{query_STRING} [L]
If .htaccess must not change
Change your <VirtualHost> configuration for your DEV server project as
<VirtualHost *:80>
ServerName dev.domain.com
ServerAlias project.domain.com
DocumentRoot "/home/webserver_dir/devname/projectname"
</VirtualHost>
These changes would typically go in your httpd-vhosts.conf file. Your .htaccess files would now have
RewriteBase /
to mark root as your base directory for both your development and live servers.
If you're trying to version your projects or test multiple projects on the same dev host, then you would have to incorporate the naming scheme into the domain names instead of the URL path. For example,
<VirtualHost *:80>
ServerName dev1.domain.com
ServerAlias project1.domain.com
DocumentRoot "/home/webserver_dir/dev1/project1"
</VirtualHost>
<VirtualHost *:80>
ServerName dev2.domain.com
ServerAlias project2.domain.com
DocumentRoot "/home/webserver_dir/dev2/project2"
</VirtualHost>
The bottom line is that you can not have the same .htaccess file rules working untouched with different deployment directories unless you resort to mod-rewrite way of if-else mumbo jumbo which would just be added clutter once you've gone live.
For the rules to work transparently, Apache must only see and apply the rules on what's going live (the content that comes after /devX/projectX/ directories) which is what shifting the DocumentRoot does here for us.
If minimal mods to .htaccess are okay
Not everyone has access to Apache's .conf files. Certain hosts out-rightly reject requests to modify them. Which is why, if they have at least kept mod-rewrite enabled, a lot of website's settings can be tinkered with. One of them is to use RewriteBase to handle the different deployment directories.
So, if you keep RewriteBase / on live but change it to RewriteBase /devX/projectX/ for development, most of your RewriteRules should work as is. So, /devname/projectname/ should correctly redirect to /devname/projectname/en/.
Your use of ([a-z{2}]+) is incorrect. You probably meant ([a-z]{2}) to capture exactly two letters. If you meant to capture two or more, it would become ([a-z]{2,}). So, your default load rewrite would become
RewriteRule ^([a-z]{2})/?$ index.php?controller=contents&method=viewHome&lang=$1 [NC,L,QSA] # Default load
You're correct to assume that you would need this regex for all subsequent rules or they would fail to match. So, your RewriteRule for casestudies won't work. A simpler way to not care about the language prefix is to drop the ^ start of URL path anchor as
RewriteRule /casestudies/([^/\.]+).html$ index.php?controller=contents&method=viewCasestudy&link=$1 [NC,L,QSA]
RewriteRule /products/([^/\.]+).html$ index.php?controller=contents&method=viewProduct&link=$1 [NC,L,QSA]
Your last RewriteRule matching ^(/)?$ isn't required because you're already doing a 301 redirect for all URLs with no language directory prefix to /en/$1 above, which should ideally be
RewriteCond %{REQUEST_URI} !^/(en|sw)(/|$) [NC]
RewriteRule ^(.*)$ en/$1 [R=301,L]
Otherwise, /en would get redirected as well to /en/en.
I'm trying to redirect all insecure HTTP requests on my site (e.g. http://www.example.com) to HTTPS (https://www.example.com). How can I do this in .htaccess file?
By the way, I'm using PHP.
The Apache docs recommend against using a rewrite:
To redirect http URLs to https, do the following:
<VirtualHost *:80>
ServerName www.example.com
Redirect / https://www.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
This snippet should go into main server configuration file, not into .htaccess as asked in the question.
This article might have come up only after the question was asked and answered, but seems to be the current way to go.
Update: Although this answer has been accepted a few years ago, note that its approach is now recommended against by the Apache documentation. Use a Redirect instead. See this answer.
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
I'd recommend with 301 redirect:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
As I was saying in this question, I'd suggest you avoid redirecting all HTTP requests to their HTTPS equivalent blindly, as it may cause you a false impression of security. Instead, you should probably redirect the "root" of your HTTP site to the root of your HTTPS site and link from there, only to HTTPS.
The problem is that if some link or form on the HTTPS site makes the client send a request to the HTTP site, its content will be visible, before the redirection.
For example, if one of your pages served over HTTPS has a form that says <form action="http://example.com/doSomething"> and sends some data that shouldn't be sent in clear, the browser will first send the full request (including entity, if it's a POST) to the HTTP site first. The redirection will be sent immediately to the browser and, since a large number of users disable or ignore the warnings, it's likely to be ignored.
Of course, the mistake of providing the links that should be to the HTTPS site but that end up being for the HTTP site may cause problems as soon as you get something listening on the HTTP port on the same IP address as your HTTPS site. However, I think keeping the two sites as a "mirror" only increases the chances of making mistakes, as you may tend to make the assumption that it will auto-correct itself by redirecting the user to HTTPS, whereas it's often too late. (There were similar discussions in this question.)
This is the html redirect approach it works but not the best.
<meta http-equiv="Refresh" content="0;URL=https://www.example.com" />
PHP approach
<?php
function redirectTohttps() {
if ($_SERVER['HTTPS']!="on") {
$redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("Location:$redirect");
}
}
?>
.htaccess approch
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
copied from:
www.letuslook.org
I found out that the best way for https and www on domain is
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
I like this method of redirecting from http to https. Because I don't need to edit it for each site.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Using the following code in your .htaccess file automatically redirects visitors to the HTTPS version of your site:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you have an existing .htaccess file:
Do not duplicate RewriteEngine On.
Make sure the lines beginning RewriteCond and RewriteRule immediately follow the already-existing RewriteEngine On.
The best solution depends on your requirements. This is a summary of previously posted answers with some context added.
If you work with the Apache web server and can change its configuration, follow the Apache documentation:
<VirtualHost *:80>
ServerName www.example.com
Redirect "/" "https://www.example.com/"
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
But you also asked if you can do it in a .htaccess file. In that case you can use Apache's RewriteEngine:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
If everything is working fine and you want browsers to remember this redirect, you can declare it as permanent by changing the last line to:
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
But be careful if you may change your mind on this redirect. Browsers remember it for a very long time and won't check if it changed.
You may not need the first line RewriteEngine On depending on the webserver configuration.
If you look for a PHP solution, look at the $_SERVER array and the header function:
if (!$_SERVER['HTTPS']) {
header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
}
This is the proper method of redirecting HTTP to HTTPS using .htaccess according to GoDaddy.com. The first line of code is self-explanatory. The second line of code checks to see if HTTPS is off, and if so it redirects HTTP to HTTPS by running the third line of code, otherwise the third line of code is ignored.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
https://www.godaddy.com/help/redirect-http-to-https-automatically-8828
Add the following code to the .htaccess file:
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^ https://[your domain name]%{REQUEST_URI} [R,L]
Where [your domain name] is your website's domain name.
You can also redirect specific folders off of your domain name by replacing the last line of the code above with:
RewriteRule ^ https://[your domain name]/[directory name]%{REQUEST_URI} [R,L]
Do everything that is explained above for redirection. Just add "HTTP Strict Transport Security" to your header. This will avoid man in the middle attack.
Edit your apache configuration file (/etc/apache2/sites-enabled/website.conf and /etc/apache2/httpd.conf for example) and add the following to your VirtualHost:
# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so
<VirtualHost 67.89.123.45:443>
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>
https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
To redirect all http requests to https , you can use :
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]
If mod-rewrite isn't enabled and you are on apache 2.4, you can also use a Redirect inside if directive to redirect http requests to https .
Apache 2.4.
<if "%{HTTPS} !~ /on/">
Redirect / https://www.example.com/
</if>
If you are in a situation where your cannot access the apache config directly for your site, which many hosted platforms are still restricted in this fashion, then I would actually recommend a two-step approach. The reason why Apache themselves document that you should use their configuration options first and foremost over the mod_rewrite for HTTP to HTTPS.
First, as mentioned above, you would setup your .htaccess mod_rewrite rule(s):
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Then, in your PHP file(s) (you need to do this where ever it would be appropriate for your situation, some sites will funnel all requests through a single PHP file, others serve various pages depending on their needs and the request being made):
<?php if ($_SERVER['HTTPS'] != 'on') { exit(1); } ?>
The above needs to run BEFORE any code that could potentially expose secure data in an unsecured environment. Thus your site uses automatic redirection via HTACCESS and mod_rewrite, while your script(s) ensure no output is provided when not accessed through HTTPS.
I guess most people don't think like this, and thus Apache recommends that you don't use this method where possible. However, it just takes an extra check on the development end to ensure your user's data is secure. Hopefully this helps someone else who might have to look into using non-recommended methods due to restrictions on our hosting services end.
Unless you need mod_rewrite for other things, using Apache core IF directive is cleaner & faster:
<If "%{HTTPS} == 'off'">
Redirect permanent / https://yoursite.com/
</If>
You can add more conditions to the IF directive, such as ensure a single canonical domain without the www prefix:
<If "req('Host') != 'myonetruesite.com' || %{HTTPS} == 'off'">
Redirect permanent / https://myonetruesite.com/
</If>
There's a lot of familiarity inertia in using mod_rewrite for everything, but see if this works for you.
More info: https://httpd.apache.org/docs/2.4/mod/core.html#if
To see it in action (try without www. or https://, or with .net instead of .com): https://nohodental.com/ (a site I'm working on).
Redirect 301 / https://example.com/
(worked for me when none of the above answers worked)
Bonus:
ServerAlias www.example.com example.com
(fixed https://www.example.com not found)
take this code to you .htaccess file
Redirect HTTP to HTTPS automatically
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The above things are for the Apache server only. What if running PHP at tomcat?
So you can use PHP code, whether it is Apache/tomcat/Nginx etc...
if (!((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))){
$redirect = 'https://' . str_replace($_SERVER['SERVER_PORT'], 8443, $_SERVER['HTTP_HOST']) . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
}
After lots of tries by considering without www and with www this works this
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} (www\.)?yourdomain.com
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Through .htaccess This will help.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
Also, Refer this for More Detail. How To Redirect Http To Https?
I found a method to force all pages of my site redirect from http to analog of pages on https that work for me.
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
This redirects all the URLs to https and www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
If you want to do it from the tomcat server follow the below steps
In a standalone Apache Tomcat (8.5.x) HTTP Server, how can configure it so if a user types www.domain.com, they will be automatically forwarded to https(www.domain.com) site.
The 2 step method of including the following in your [Tomcat_base]/conf/web.xml before the closing tag
step 1:
<security-constraint>
<web-resource-collection>
<web-resource-name>HTTPSOnly</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
and setting the [Tomcat_base]/conf/server.xml connector settings:
step 2:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="443"/>
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="[keystorelocation]" type="RSA" />
</SSLHostConfig>
</Connector>
Note: If you already did the https configuration and trying to redirect do step 1 only.
Not only can you do this in your .htaccess file, you should be doing this period. You will also want to follow the steps here to get your site listed on the HSTS preload list after you implement this redirect so that any requests to the insecure http version of your website never make it past the user agent. Instead, the user agent checks the requested URI against a baked in list of https only websites and, if the requested URI is on that list, changes the protocol from http to https before transmitting the request to the server. Therefore, the insecure request never makes it out into the wild and never hits the server. Eventually when the internet changes over to https only the HSTS preload list will not be needed. Until then, every site should be using it.
In order to perform the redirect, we need to enable the rewrite engine and then redirect all traffic from the http port 80 to https.
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://yourwebsite.tld/$1 [L,R=301]
I tried all .htaccess configurations I could find on the internet but none worked.
Then, I realized Apache discourages using mod_rewrite.
My solution was to edit apache configuration files under the following folder:
/etc/apache2/sites-enabled
You will have one mandatory file named 000-default.conf and an ssl configuration file named 000-default-le-ssl.conf (if you have installed ssl certificate from letsencrypt/certbot). However, these files can be named differently depending on the file names you provided when setting up the site.
In 000-default.conf, I edited the following inside <VirtualHost *:80> as:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
In 000-default-le-ssl.conf, I edited the following inside <VirtualHost *:80> as:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
No other redirection is needed.
Save the file then restart the apache server using sudo service apache2 restart
I was actually trying to get this to work on an EC2 instance without a load balancer since that costs money. I've read everywhere that .htaccess isn't the "right" way to do it. Obviously, it will work, but I was trying to keep things by the book. I was following all of the examples to update the httpd.conf file and adding a lot of unnecessary stuff. It turns out the only line you really need is this:
Redirect permanent / https://www.yourdomain.com
My problem was that originally I had added this in a VirtualHost tag inside of httpd.conf, which is what a lot of posts tell you to do, but it wasn't working. It turns out there was a separate conf file stored in /etc/httpd/conf.d called yourdomain.conf which already had the VirtualHost tag and was overriding my httpd.conf settings. I just added the above line inside of it and voila, it instantly redirected to https. There is no need for the separate VirtualHost for port 443.
It's working now and the VirtualHost tag looks like this:
<VirtualHost *:80>
ServerName yourdomain.com
DocumentRoot /var/www/html
ServerAlias www.yourdomain.com
ErrorLog /var/www/error.log
CustomLog /var/www/requests.log combined
Redirect permanent / https://www.yourdomain.com
</VirtualHost>
Note: I already had TLS setup with a FREE certificate from certbot (Love those guys) and was just trying to redirect regular http calls to the working https site.
If you are using Apache, mod_rewrite is the easiest solution, and has a lot of documentation online how to do that. For example: http://www.askapache.com/htaccess/http-https-rewriterule-redirect.html
A different edge to this problem is when a Load Balancer comes into play.
The situation is as follows:
- Traffic from browser to Load Balancer, and back, is (should be) HTTPS
- Traffic between Load Balancer and actual WebServer is HTTP.
So, all server request variables in PHP or Apache show that the connection is just HTTP. And the HTTP and HTTPS directories on the Server are the same.
The RewriteCondition in the approved answer does not work.
It gives either a loop or it just doesn't work.
Question is: How to get this working on a Load Balancer.
(Or is the Load Balancer configured wrong. Which is what I'm hoping for because then I can move the problem over to the WebHosting company :-) )
If you're using an Amazon Web Services Elastic Load Balancer which accepts https traffic and routes it to your server(s) with http, the correct way to redirect all http traffic to https is described here: https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb
Use the X-Forwarded-Proto header (contains http or https) which is always included in http requests from the load balancer, as described here: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
In the httpd.conf file:
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
</VirtualHost>
Or in your root .htaccess file:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
Bonus: it will not try to redirect http traffic on your local development machine.
It works for me:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
and for example, http://server/foo?email=someone%40example.com redirects normally without any issues.
The file .htaccess located in the website root folder (for example named public_html).
It is possible to use
RewriteCond %{SERVER_PORT} !^443$ instead RewriteCond %{HTTPS} !on