Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Username and Password in django request header returns None

I'm creating a view which is expected to be accessed by a bot passing a username and password in the header. (It's a google feed bot to be specific). However, I can never seem to access the username and password to authenticate the bot's credentials. request.GET.get('username') and request.GET.get('password') both return None since both request.GET and request.POST return empty QueryDicts. I am using Postman with basic authentication to test my requests. Here is my code from views.py:

def authenticate_bot(request):
    username = request.GET.get('username')
    password = request.GET.get('password')
    feed_bot = authenticate(username=username, password=password)

    if feed_bot is not None:
        # Confirmed as user credentials.
        login(request, feed_bot)

How do I retrieve the username and password from my basic authentication header?

like image 844
turtlefranklin Avatar asked Jun 24 '16 15:06

turtlefranklin


2 Answers

Thank you nthall for pointing me in the right direction - finding the request.META dictionary was key.

Since I couldn't find much in the way of resources which explained the process, I'll post the entire Django process for retrieving and authenticating data from the Authorization header here.

import base64
from django.contrib.auth import authenticate

def header_auth_view(request):
    auth_header = request.META['HTTP_AUTHORIZATION']
    encoded_credentials = auth_header.split(' ')[1]  # Removes "Basic " to isolate credentials
    decoded_credentials = base64.b64decode(encoded_credentials).decode("utf-8").split(':')
    username = decoded_credentials[0]
    password = decoded_credentials[1]
    feed_bot = authenticate(username=username, password=password)
    # if the credentials are correct, then the feed_bot is not None, but is a User object.

Django capitalizes and affixes the 'HTTP_' prefix to any header passed in the request, and as nthall correctly pointed out, it can be accessed via request.META.

I isolate the base64 encoded information, which is in the format 'Basic username:password' by splitting the header over the space so it's just 'username:password'. Then I decode using base64 and then decode the result to convert the byte-like string to a utf-8 string. Then it's just a matter of isolating the username and password. Then go through the process of authentication.

like image 126
turtlefranklin Avatar answered Sep 24 '22 05:09

turtlefranklin


Neither request.GET nor request.POST refers to request headers. The data you're looking for is most likely available in the dictionary at request.META -- more details on that in the HttpRequest docs. Not sure about the details of your setup but it sounds like you'd be looking for request.META['username'] and request.META['password']

like image 45
nthall Avatar answered Sep 21 '22 05:09

nthall