HTTP_AUTHORIZATION header in Django - python

I wrote a simple check in django which requires an access token to be passed along in some requests (I'm using a decorator).
authorization = request.META.get('HTTP_AUTHORIZATION', None)
# Forbid access when no access token, or an invalid one, is provided
form = AccessTokenForm({ 'access_token': authorization })
if not form.is_valid():
raise exceptions.HttpDeniedException()
This has been working fine with django's development server, but recently I deployed using Apache and now it doesn't work anymore, as the authorisation variable is None. Has anyone faced something similiar before? The client is passing the header as Authorization; again, this is working fine in localhost, but not on the remote server.
Edit: I found this, and it seems that it should work, but it doesn't. Actually, I didn't even have an .htaccess file, and adding one doesn't seem to have taken any effect at all. Here are the contents:
RewriteEngine On
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(static/.*)$ - [L]
RewriteCond %{REQUEST_URL} !(dispatch.fcgi)
RewriteRule ^(.*)$ dispatch.fcgi/$1 [QSA,L,E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
The thing is, I'm not even sure Apache is using this at all..

It seems there's a ticket for this issue here. Just add the following to apache2.conf:
WSGIPassAuthorization on

Related

Enable Website access from both www and non-www

I recently hosted my site on Cpanel, however, I am still not able to find the right solution for my problem.
I intend to make my site accessible from www.site.com too.
Currently accessing the site using the above returns the following on the browser
This site can’t be reached
www.site.com’s server IP address could not be found.
Try:
Checking the connection
Checking the proxy, firewall, and DNS configuration
ERR_NAME_NOT_RESOLVED
How can I make the site accessible using www.site.com as well? Probably using .htaccess file
Adding the following on my .htaccess file still does not work
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
</IfModule>
It's a Python app
I can see that you are getting the error "ERR_NAME_NOT_RESOLVED". This means that the DNS record for www.site.com is missing. You need to add a CNAME or A record for www.site.com to point to the IP address of your server.
You can add the records from cPanel >> Zone editor.
https://docs.cpanel.net/cpanel/domains/zone-editor/
This works only if your nameservers are the same as your hosting server. If you are using any other nameserver you will need to add the records on it.

Django Public URL Rewrite

I am deploying a Django application to an environment which requires a user login for everything by default, however allows you to specific URLs you want to display without a login if you start the URL with /public, for instance /public/forums (this is a security measure to have everything protected by default and explicitly define what should be publically accessible).
I decided just to prefix all the URLs I want public in urls.py with /public. This works, however I don't want /public to be shown. I added to the .htaccess:
RewriteEngine On
RewriteCond %{THE_REQUEST} /public/([^\s?]*) [NC]
RewriteRule ^ %1 [L,NE,R=302]
RewriteRule ^((?!public/).*)$ public/$1 [L,NC]
however, my server is coming back with LimitInternalRecursion.
How can I fix this to achieve a URL without public?
Your RewriteCond is being triggered by your RewriteRule. That is, you are rewriting to a URL that fires your rewrite, hence the recursion error. This is because your regular expression in RewriteCond %{THE_REQUEST} /public/([^\s?]*) [NC] is catching everything, even /public/forums/. Check out this saved example: https://regex101.com/r/dI8cH4/1. And try getting a simpler rewrite to work first (like to your landing/home page):
Options +FollowSymLinks
RewriteEngine On
RewriteRule /public/ http://example.com/

Why does my django web app on shared hosting have its GET urls treated differently than POST urls

I have a django web app on A2hosting, where I am using .htaccess files and passenger_wsgi.py. It was working fine the last time I touched it, but then someone who had a look at it later informed me that it was broken.
I created a test situation to find the problem and here's the gist of it.
When I do a GET (to www.geo4ce.com/quiz/test_weird/), it goes to a page with a simple form that just has one input and a submit and an action that has "/quiz/test_weird/" and method="post". When I submit the form, the server expects the "quiz" part of the url to be referring to a path on the file server, can't find it and then logs an error that it can't find it. But, then it checks the test_weird part of the url against my django urls.py file, finds a different view for that and displays it.
A scenario that almost works properly is with www.geo4ce.com/quiz/test_hacked/, that has the same set up, except the form has action = "/anythinghere/quiz/test_hacked/". In this case, the "anythinghere" part of the url gets an error logged, since it doesn't exist on the file server, and then the /quiz/test_hacked/ part of the url works normally to get back to the original web page.
Anyone have any idea how I might be able to fix or debug this?
[EDIT]
I don't think it's the .htaccess file that's the cause. It looks something like this.
PassengerEnabled On
PassengerAppRoot /path/to/app/folder/
# Prevent Apache from serving .htaccess files:
<FilesMatch "^\.htaccess">
Order allow,deny
Deny from all
</FilesMatch>
deny from xxx.yyy.zzz
Apparently the issue is caused by a certain version of Passenger (with RoR). I've been told to switch to using FCGI.

Python Flask mod-wsgi Custom Headers not in Request

I've a simple Python Flask application, which is being served by Apache via mod_wsgi.
The part of my application which works perfectly on my localhost, but does not work through mod_wsgi is the accessing of custom request headers.
When I request a certain web page, I pass it a header called auth_user. On my localhost, I am able to access this header as: request.headers["auth_user"], which works great. However when served through Apache and mod_wsgi, this custom header does not exist! Printing all request.headers shows that the standard Content-Type, Cache-Control headers are sent, but not the auth_user header which i've been sending to my localhost with no problem.
Tcpdump shows that the server is receiving the header, but it is not available in my request.headers.
Does anyone have any idea why this header is not being made available within the app?
Well this one took me many hours...
Turns out that only alphanumeric characters or '-' are allowed.
Any headers not conforming these will be ignored.
http://modwsgi.readthedocs.org/en/latest/release-notes/version-4.3.0.html <- Bug fixes, point 2.
The solution is to set the claim prefix to something without _ like
OIDCClaimPrefix OIDC-CLAIM-
Ensure your Apache configuration has the WSGIPassAuthorization directive set to 'On' so your headers get past Apache + WSGI and to your Flask app.

How to hide "cgi-bin", ".py", etc from my URLs?

Brand new to web design, using python. Got Apache up and running, test python script working in cgi-bin directory. Get valid results when I type in the URL explicitly: ".../cgi-bin/showenv.py"
But I don't want the URL to look that way. Here at stackoverflow, for example, the URLs that display in my address bar never have the messy details showing the script that was used to run them. They're clean of cgi-bin, .py, etc. extensions. How do I do that?
EDIT: Thanks for responses, every single one helpful, lots to learn. I'm going with URL Rewriting for now; example in the docs looks extremely close to what I actually want to do. But I'm committed to python, so will have to look at WSGI down the road.
The python way of writing web applications is not cgi-bin. It is by using WSGI.
WSGI is a standard interface between web servers and Python web applications or frameworks. The PEP 0333 defines it.
There are no disadvantages in using it instead of CGI. And you'll gain a lot. Beautiful URLs is just one of the neat things you can do easily.
Also, writing a WSGI application means you can deploy on any web server that supports the WSGI interface. Apache does so by using mod_wsgi.
You can configure it in apache like that:
WSGIScriptAlias /myapp /usr/local/www/wsgi-scripts/myapp.py
Then all requests on http://myserver.domain/myapp will go to myapp.py's application callable, including http://myserver.domain/myapp/something/here.
example myapp.py:
def application(environ, start_response):
start_response('200 OK', [('Content-type', 'text/plain')])
return ['Hello World!']
I think you can do this by rewriting URL through Apache configuration. You can see the Apache documentation for rewriting here.
You have to use URL Rewriting.
It is not a noob question, it can be quite tricky :)
http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
Hope you find it helpful
this is an excerpt from a .htaccess that I use to achieve such a thing, this for example redirects all requests that were not to index.php to that file, of course you then have to check the server-variables within the file you redirect to to see, what was requested.
Or you simply make a rewrite rule, where you use a RegExp like ^.*\/cgi-bin\/.*\.py$ to determine when and what to rewrite. Such a RegExp must be crafted very carefully, so that rewriting only takes place when desired.
<IfModule mod_rewrite.c>
RewriteEngine On #activate rewriting
RewriteBase / #url base for rewriting
RewriteCond %{REQUEST_FILENAME} !index.php #requested file is not index.php
RewriteCond %{REQUEST_FILENAME} !^.*\.gif$ #requested file is no .gif
RewriteCond %{REQUEST_FILENAME} !^.*\.jpg$ #requested file is no .jpg
RewriteCond %{REQUEST_FILENAME} !-d #is not a directory
RewriteRule . /index.php [L] #send it all to index.php
</IfModule>
The above Example uses RewriteConditions to determine when to rewrite ( .gif's, .jpeg's and index.php are excluded ).
Hmm, so thats a long text already. Hope it was a bit helpful, but you won't be able to avoid learning the syntax of the Apache RewriteEngine.
You'll find the ScriptAlias directive helpful. Using
ScriptAlias /urlpath /your/cgi-bin/script.py
you can access your script via http://yourserver/urlpath.
You also might want to look into mod_passenger, though the last time I used it, WSGI was kind of a "second-class citizen" within the library—it could detect WSGI scripts if it were used to serve the whole domain, but otherwise there are no directives to get it to run a WSGI app.
Just use some good web framework e.g. django and you can have such URLs
more than URLs you will have a better infrastructure, templates, db orm etc

Categories

Resources