I want to put basic HTTP authentication somewhere in my code if a certain condition is met. The condition is a request parameter. To simplify, let's say I want it in a Django view.
I know how to do it in PHP. This is the chunk of code which does exactly what I want:
if (isset($_REQUEST['key']) && $_REQUEST['key'] === 'value') {
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if user hits Cancel button';
exit;
} else {
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
}
}
I can put this chunk of code anywhere in my PHP script and when execution hits those lines, authentication will be requested. If authentication fails, script execution will stop and a 401 Unauthorized header will be sent with the specified message. This is what I want in Python/Django. Here is a chunk of code, help me fill it in:
def some_view(request):
if request.REQUEST.get('key') == 'value':
# FILL ME IN
What I want:
What I DON'T want:
from django.http import HttpResponse
def some_view(request):
if request.REQUEST.get('key') == 'value':
if not request.user.is_authenticated():
response = HttpResponse('Text to send if user hits Cancel button', status=401)
response['WWW-Authenticate'] = 'Basic realm="My Realm'
return response
...
This will return a 401
status code, but requires you to provide your own content/template. If it is acceptable for you to return a 403
status code, you can use the built-in PermissionDenied
exception that returns a 403 page based on your '403.html' template:
from django.core.exceptions import PermissionDenied
def some_view(request):
if request.REQUEST.get('key') == 'value':
if not request.user.is_authenticated():
raise PermissionDenied
...
EDIT:
To implement HTTP Basic Authentication, you have to set up your webserver (Apache, nginx, whatever you're using) to handle this. You should check your webserver's documentation on how to do this.
Django implements a RemoteUserBackend
to allow users to login using basic authentication, but this uses the same user model as the normal ModelBackend
, so these are not separate. Luckily, the middleware and the backend are quite simple. The webserver will deny any request with invalid credentials, so any time the 'REMOTE_USER'
header (or whatever header value you use) is set, the user is properly authenticated. This header will be available in request.META
, so to check if a user is authenticated using Basic Authentication, you can use this code:
from django.http import HttpResponse
def some_view(request):
if request.REQUEST.get('key') == 'value':
if request.META.get('REMOTE_USER', None):
do_something()
else:
response = HttpResponse('Text to send if user hits Cancel button', status=401)
response['WWW-Authenticate'] = 'Basic realm="My Realm'
return response
...