Rewrite URL in Nginx proxy + apache setup - django

I'm working in python/django with apache and a Nginx proxy.
I need to transform some URLs like these:
www.mydomain.com/client_A/
www.mydomain.com/client_B/
to
www.mydomain.com/clients/1/
www.mydomain.com/clients/2/
I would do a rewrite in the Nginx configuration, but the problem is that this should Not be visible to the user, rather he should keep seeing the URL as www.mydomain.com/client_A/ and Not as the internal URL.
The main idea is to do this in the Nginx/Apache configuration
Thanks in advance.

I believe
rewrite ^/client_A/(.*)$ /clients/1/$1 last;
in nginx config should work.

You might want to look into the following post for related question.
apache reverse proxy changes url
The idea is to use a reverse proxy with Apache to keep URLs same.

Related

Django behind reverse proxy ?next= issue

I have deployed a Django application behind an nginx reverse proxy. This proxy handles multiple Django applications
So the main url is for example https://www.example.com
and then I use the reverse proxy to redirect to the specific Django application using subdirectory
for example https://www.example.com/myapp
The problem is that if I logout from myapp and try to access a page that requires login the redirect link is wrong, instead of
https://www.example.com/myapp?next=/mainpage
it gives me
https://www.example.com/?next=/myapp/mainpage
which is wrong since "myapp" cannot listen to requests from https://www.example.com/
Is there any way I can force Django to understand that the default url is https://www.example.com/myapp and not https://www.example.com?
Thanks

nginx, django and url mapping

The admins where I work have a url http://company.com/app, public facing. They use apache http server. The sysadmins have http://company.com/app pointing to http://internal_ip_address:8080. I have nginx sitting on http://internal_ip:address listening on 8080. I am trying to get nginx to take requests coming into internal_ip_address, route the requests to localhost:9000 which is a django app. Once django is done with the request the resulting page renders with appropriate public facing url (e.g. http://company.com/app . . .) Thanks for any help!
Thanks to all those that tried to help. After spending a notable amount of time on the issue I determined that it was a http server config issue on a server managed elsewhere.

Can I set up a CNAME catch-all redirect from one subdomain level to a higher subdomain?

I have hundreds of subdomains set up for environments in Route53 for AWS that look like this:
<appX>.dev.internalurl.us
<appX>.qa.internalurl.us
<appX>.pt.internalurl.us
<appX>.internalurl.us
The issue is that our production internal urls are missing the 'prod' env in the url which requires us to add conditionals to all our config scripts, like:
if 'prod.' in url:
url = url.substring('prod.', '')
What I'd like is:
<appX>.prod.internalurl.us to go to <appX>.internalurl.us automatically.
EDIT:
I added a CNAME to route prod.internalurl.us to internalurl.us like so:
*.prod.internalurl.us > internalurl.us
but this obviously won't work since I need a capture group on the wildcard! It's ignoring the first "appX" subdomain.
I don't want to have to enter in hundreds of CNAMES,so am looking for a catch-all redirect for one sub-domain level to its parent.
Is there a way to do this with CNAME or does it require running an nginx proxy at prod.internalurl.us to make this work?
The solution that may help is simple enough. To find it out let me ask a question. Why do you need this functionality on DNS level?
What I'd like is:
.prod.internalurl.us to go to .internalurl.us
automatically.
CNAME doesn't help with conditional URL rewrite, there is no such logic on that layer. What helps is HTTP layer 301 redirect can be managed via Nginx:
server {
server_name ~^(?<app>.+)\.prod\.internalurl\.us$;
return 301 http://$app.internalurl.us$request_uri;
}
There is no proxy but HTTP 301 redirect instead.

Nginx+FastCGI+Django Remove URL Prefix before passing to Django

I've setup Nginx to fastcgi_pass to Django and don't want to serve Django from "/". I want to prefix the URLs with something like "/django/sample/" but then have Nginx remove that prefix before it gets passed to Django - this way Django's internals will act like it's actually serving from "/".
I've tried updating the Django app to include the prefix in the URLs routed, like this:
urlpatterns = patterns('',
'^', include(base_urlpatterns), # iff you wish to maintain the un-prefixed URL's too
'^your_prefix/', include(base_urlpatterns),
)
And I currently do a fastcgi_pass like so:
#django sample
location /django/sample {
include fastcgi_params;
fastcgi_pass 127.0.0.1:8024;
}
But this isn't a graceful solution as any URL in my django app then has to make sure to include a prefix like "/django/sample". And it also means that when I run locally VS on the server the URLs may need to be different.
I build quite a few django apps that'll be running from one server and don't want to always have to do this tom-foolery with URLs and remember to update all the URLs in Django.
I've been googling for a while trying to figure out how to do this with nginx but haven't seen anything.
So, I'm looking to use Nginx to remove the "/django/sample" in the request before it gets passed to Django. Anyone done this before?
You're approaching this the wrong way round. There's no reason to remove the prefix before passing to Django: as long as you configure your server correctly, Django will be aware of it, and will automatically use it in things like the {% url %} tag and reverse() call (which of course you're using for all your URL references internally).
The documentation for deploying with FastCGI gives some details of how to set the prefix, in particular the advice that if you can't get it to work any other way, you can explicitly set FORCE_SCRIPT_NAME to the value of your prefix.

Running the django admin over https using apache2

I have a django web application that's running on apache 2.2.14 and I want to run the admin application over https.
Having read considerable discussions on using a proxy, writing middleware, running alternative wsgi scripts, the chaps in #httpd came to my rescue. The solution is so simple, I was surprised I didn't find it online, so I'm curious to see if I've made some glaring assumptions or errors.
One complication was that I also wanted to run one of my django apps in the site over https, that is everything on /checkout.
Essentially, if a user requests a URI starting with /admin or /checkout on http, they are to be redirected to that URI but on https. Conversely, if a user requests a URI that does not start with /admin or /checkout on https, they are to be redirected to that URI but on http.
The key to solving this problem was to use Redirect and RedirectMatch directives in my VirtualHost configuration.
<VirtualHost *:80>
... host config stuff ...
Redirect /admin https://www.mywebsite.com/admin
Redirect /checkout https://www.mywebsite.com/checkout
</VirtualHost>
<VirtualHost *:443>
... ssl host config stuff ...
RedirectMatch ^(/(?!admin|checkout).*) http://www.mywebsite.com$1
</VirtualHost>
Another approach is to use #secure_required decorator. This will automatically rewrite the requested url and redirect to https://... version of the URL. Then you don't have to have Redirect in *:80 configuration. *:443 configuration may still be required for performance purpose if you want other traffic to go through normal http traffic.
I tried your solution, but ran into several problems. First, the formatting on the admin site disappeared, as if it could not find the admin static files. Second, if I tried to reach the non-admin site through https, the browser would not find it and redirect me to Yahoo search. Oddly, if I edited the yahoo search URL to eliminate all text except my correct URL (minus the http://), it would continue to search through yahoo for my site. However, typing the exact same URL afresh sent me to my site.
I solved all of these issues by simply removing the
RedirectMatch ^(/(?!admin|checkout).*) http://www.mywebsite.com$1
directive.
I should mention that I don't have a /checkout section on my site and am only trying to secure /admin. ... and yes, I did substitute my URL for "mywebsite.com"
What you described should work, but there may be a problem in the future if you need to make changes to which paths are/are not HTTPS. Because this method requires the ability to correctly modify the Apache config file it means you do not want novices in the loop. Screw up the config file and your site can go 500-error in the blink of an eye.
We chose to have a simple text file that had a list of the must-be-HTTPS paths. Anyone on the project can edit it and it is checked for correctness when it is loaded. We handle any needed redirects to/from HTTPS in middleware and it seems to work just fine. This method will also work if you are running anything other than Apache.