I'm trying to setup an apache server with a somewhat complex htaccess rules. I have found various solutions for individual rules, however, when I try to put the whole picture together I lack experience with htaccess to make it work and I experience some weird rewrites.
Rules:
The root contains index.php which launches a single page UI app. That means that URLs should be rewritten to /index.php
There are a few folders which should be exempt from Rule #1, e. g. if /admin is accessed, /admin/index.php should be shown, not /index.php.
Rule #2 also applies to all files on the server (so that the UI app can load resources like js/css/etc.)
All http://* requests should be redirected to https://*
Some possibly relevant details:
The server has a LetsEncrypt SSL certificate installed. The "redirect from http" was enabled during installation, I figured it might've created some weird rewrite rules, so I navigated to etc/apache2/sites-available/lamp-server.conf and commented out these three lines
#RewriteEngine on
#RewriteCond %{SERVER_NAME} =[DOMAIN]
#RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
Here's the relevant part of /.htaccess. There are no other rewrites/redirects in this file.
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(wp|admin|phpmyadmin)(/.*)?$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php [QSA]
RewriteCond %{HTTPS} !on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
When I clear the cache in browsers, it seems to work correctly for a while. But when I open the SPA part of the server (i. e., the first RewriteRule is triggered), the browser caches some sort of rewrite and then /admin also starts pointing to the SPA, unless I do a Ctrl+F5 each time.
I tried executing GET requests via Fiddler 4, everything seems to be working correctly there. Tried these scenarios:
HTTP root - got a 302 redirect.
HTTPS root - 200 OK.
/search SPA page - got 200 OK with rendered /index.php as response.
/admin page outside of SPA - got 200 OK with rendered /admin/index.php as response.
During the development of the htaccess rules there might've been a time when a 301 redirect was executed, which is now messing with my browser cache. However, then it's weird that even if I install a new fresh browser, it gets affected by the issue. Even if I try to access it from my mobile (which I never did before, so there's nothing cached), the same issue happens.
Related
I have an issue with mod_rewrite and I can't seem to solve it. I stripped the example down to the bare bones and I don't understand why a specific rule forces my browser to redirect instead of rewrite:
RewriteEngine on
#if request is for a physical-file OR for one of the language paths - skip (return as-is)
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{REQUEST_URI} ^/de [OR]
RewriteCond %{REQUEST_URI} ^/en-US
RewriteRule ^ - [L]
#otherwise: rewrite to en-US folder
RewriteRule ^(.*)$ /en-US/$1 [NC,L,QSA]
I read the documentation very carefully and it seems like this should actually rewrite every call, so https://example.com/fuBar.html should actually retrieve the file /en-US/fuBar.html from my server - the users browser shouldn't know about it.
What's really happening is that for some reason the browser is redirected to https://example.com/en-US/fuBar.html. While this does display the correct content, it's just not what I want or what I thought this RewriteRule should do. What am I doing wrong?
*add - the .htaccess of the subfolders de and en-US:
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
There's nothing in the code you've posted that would trigger an external "redirect".
Make sure you have cleared your browser (and any intermediary) cache(s) to ensure you are not seeing an earlier/erroneous 301 (permanent) redirect. (301 redirects are cached persistently by the browser.)
Check the "network traffic" in the browser's developer tools to see the precise nature of this redirect to see what it redirects from/to, and well as the 3xx HTTP status code of the redirect (if indeed this is an external redirect).
It would seem the front-end (JavaScript/Angular) is manipulating the URL in the address bar (there is no redirect). From comments:
Actually there was no redirect happening at all! Rather since I set <base href="/en-US"> somehow my frontend (Angular) seems to have outsmarted me, manipulating the address without me realizing it. Turns out I don't even need to change the base href, I just need the rewrites.
1) After following the steps in this video (https://www.youtube.com/watch?v=GPcznB74GPs) on how to install free SSL using ZeroSSL, I encounter a problem that shows 404 Not Found in my website. Although i enter https://(my_domain_name).com manually in the URL, it still doesn't show the HTTPS. In my C-Panel>SSL STATUS>I can see that my domain is validated (with a green lock beside it)
2) At the end of the tutorial in the video, there is some codes that need to be placed inside .htaccess file (in the public_html root directory) in order to automatically change the URL into https:// URL. (Tutorial code as below)
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I have previously installed magento 2 and the .htaccess have its own similar code. (Magento 2 code as below)
RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php [L]
1) There are others that encounter the same problem and provide their solutions like rename my file /.well-known/acme-challenge/(FILE NAME.txt) to /.well-known/acme-challenge/(FILE NAME), however, mine does not have a .txt to begin with. There is another video that says to rename the pictures/source which had http in it to https by inspecting the page>console (It will shows mixed-content warning). However, mine does not show any mixed content warning.
2) When i tried to replace and/or add the above magento 2 code with the tutorial code, I got too_many_redirect error.
My website/domain name is www.aevuswebs.com
Go to database of your Magento & search for the table Core_config_data with in that table look for the rows with the current URL details of your website that is without SSL.
Update the detail & add 's' into both secured & unsecured base_url's something like below
http://www.example.com/ -> https://www.example.com/
Try to reload your website it will load.
I have an e-commerce site that resides in:
http://dev.gworks.mobi/
When a customer clicks on the signin link, the browser gets redirected to another domain, in order for authentication:
http://frock.gworks.mobi:8080/openam/XUI/#login/&goto=http%3A%2F%2Fdev.gworks.mobi%3A80%2Fcustomer%2Faccount%2Flogin%2Freferer%2FaHR0cDovL2Rldi5nd29ya3MubW9iaS8%2C%2F
I'm trying to rewrite http://dev.gworks.mobi/* to http://frock.gworks.mobi:8080/openam/*, without redirection.
I've tried this in the .htaccess of the dev.gworks.mobi site:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/openam(.*)$ [NC]
RewriteRule ^(.*)$ http://frock.gworks.mobi:8080/$1 [P,L]
</IfModule>
But when I access http://dev.gworks.mobi/openam, it shows a 404 page not found page.
Can anyone help me to achieve my use case?
Try this:
RewriteEngine on
RewriteBase /
# Make sure it's not an actual file being accessed
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Match the host
RewriteCond %{HTTP_HOST} ^dev\.gworks\.mobi
# Rewrite the request if it starts with "openam"
RewriteRule ^openam(.*)$ http://frock.gworks.mobi:8080/$1 [L,QSA]
This will rewrite all the requests to dev.gworks.mobi/openam to frock.gworks.mobi:8080.
If you want to mask the URI in a way that it's not visible to the visitor that she's visiting the authentication app, you need to add a P flag. Please note that it needs Apache's mod_proxy module in place:
RewriteRule ^openam(.*)$ http://frock.gworks.mobi:8080/$1 [P,L,QSA]
Feel free to drop the L flag, if it's not the last rewrite rule. See RewriteRule Flags for more information.
The 404
If it's all in place and you're still getting a 404 error, make sure that the target URL is not throwing 404 errors in the first place.
Second, check if you're still getting the error with the correct referrer URI set. It might be designed in a way to throw a 404, if the referrer is not correctly set. If that's the case, which I suspect, you need to use the R flag and redirect instead of proxying the request.
Last thing that comes to my mind, some webapps are not built in a way to figure out the URI address. The host, as well as the port number, might be hard-coded somewhere in the config files. Make sure that the authentication app is able to be run from another URL without the need to edit the configs.
Test
You can test the rewriterule online:
A little explanation and then 2 questions....
Essentially I am building a single page app to display media (by tags, by type, etc.. etc..). All the media is uploaded & tagged by me, so I am not scrapping for content or relying on 3rd party services (twitter, facebook, flickr, imgur, etc...). I am doing most of the work with JS (RequireJS modules...) and am leveraging ToroPHP for a simple, lightweight & restful API
My end goal is this:
Allow returning users to type in URLs like: / OR //, and always load my root index.php (maintaining the url). At the same time i need several subdirectories available for the api to
fetch data:
/assets/ (CSS, Font Files, Sprites or SVG Icons)
/components/ (for RequireJS scripts)
/api/ (this is just a sub directory that has a ToroPHP instance for the API)
I believe the below snippet solves this issue (I was wondering if I could get a good explanation of what this is doing though? I have pieced it together from snippets on the internet):
RewriteEngine on
RewriteRule ^/?assets/.+$ - [L]
RewriteRule ^/?components/.+$ - [L]
RewriteRule ^/?api/.+$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ /index.php [L]
Additionally, I was hoping you could help me figure out a way to only allow my "app" (that is, internal calls (is there a server user on apache?) initiated by RequireJS modules to the API) to have access to /assets/ & /components/ & /api/ so if a user types in /api/test?subject=123 they are routed to a page that isn't the index.php, but isn't the actual API either. I would like this to be the same for /components/ & /assets/ as well.
*Summary questions:
1). Help explain the code snippet above.
2). Can I allow my server access to /assets/ & /components/ & /api/ but not allow a user to type into them?
Obviously, Apache isn't my specialty, but I am fairly confident in learning.
Thanks!
Help explain the code snippet above.
RewriteEngine on
Turns on the rewrite engine, none of the rules will do anything unless the rewrite engine is turned on
RewriteRule ^/?assets/.+$ - [L]
RewriteRule ^/?components/.+$ - [L]
RewriteRule ^/?api/.+$ - [L]
These rules are called "pass-through" rules. The - target means "do nothing" and the L flag stops the rewriting for the current pass. These essentially just mean: if URI starts with /assets/, do nothing and stop rewriting. If the URI starts with /components/, do nothing and stop rewriting. If the URI starts with /api/ then do nothing and stop rewriting.
The next rule has a few conditions associated with it. The rule won't get applied unless all conditions are met:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
These check if the requested URI maps to an existing file or directory, The !-f means the request isn't for a file, and the !-d means the request isn't a directory.
RewriteCond $1 !^(index\.php)
This checks if the request doesn't start with /index.php.
Finally, if all 3 conditions are met, then:
RewriteRule ^(.*)$ /index.php [L]
rewrite whatever the request is to /index.php, and stop rewriting.
Can I allow my server access to /assets/ & /components/ & /api/ but not allow a user to type into them?
No. If someone goes to your page and your page links to something in one of these directories, the browser loads it just like it would if someone typed it into the URL address bar. The only difference is that (sometimes) the browser will include a "Referer" header request letting the server know what page told the browser to load the file. It's not always going to be used by all browsers and it can easily be forged. So checking the referer isn't going to guarantee that people can't still directly load your files.
In order to check the referer, add this right below the RewriteEngine On line:
RewriteCond %{HTTP_REFERER} !^https?://example.com/
RewriteRule ^(assets|components|api)/ - [L,F]
This is essentially a condition that checks the referer, and if it doesn't start with "http://example.com" or "https://example.com", assuming that "example.com" is your site, then the rule checks that the request starts with either /assets/, /components/, or /api/, and passes it through without changing anything, except the F flag causes the server to return a 403 Forbidden.
I've not done much with mod_rewrite, but I can't seem to get anywhere with this. I'm wondering if perhaps it is not enabled on my server(even though my host says it is).
I have the following url: http://dev.website.com/folder1/translate/horse and I want that to redirect to: http://dev.website.com/folder1/translate.php?word=horse
My .htaccess starts with RewriteEngine on and I've tried various attempts to get it working, but no matter what, it just shows my home page (the default 404 redirect).
Things I've tried:
RewriteRule ^translate/.*$ translate.php?word=$1
RewriteRule ^translate translate.php
and some other things I don't remember, but I can't get anything to work.
The .htaccess file I am using is located in folder1. I have also tried putting random characters in the file to make it throw an error, and it does.
Anything I'm missing? How would I properly create this redirect?
As per request, this is my file structure.
I have the domain www.website.com, and a subdomain dev.website.com. The subdomain is set so that it redirects to www.website.com/dev. So, in this case, dev.website.com/folder1/translate.php = www.website.com/dev/folder1/translate.php. I am not sure how that masking is done, as it is accomplished via my web host's cpanel.
You aren't capturing $1 in brackets so this should work:
In DOCUMENT_ROOT/.htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^folder1/translate/(.*)$ /folder1/translate.php?word=$1 [L,QSA]
In DOCUMENT_ROOT/folder1/.htaccess:
RewriteEngine On
RewriteBase /folder1/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^translate/(.*)$ translate.php?word=$1 [L,QSA]