This is a small tutorial on how to use HTTP authentication for your site. Firstly you need to copy this file to httpauth.py and place it at
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | import base64 from django.contrib.auth.models import User from django.http import HttpResponse from django.contrib.auth import authenticate, login ############################################################################# # def view_or_basicauth(view, request, test_func, realm = "", *args, **kwargs): """ This is a helper function used by both 'logged_in_or_basicauth' and 'has_perm_or_basicauth' that does the nitty of determining if they are already logged in or if they have provided proper http-authorization and returning the view if all goes well, otherwise responding with a 401. """ if test_func(request.user): # Already logged in, just return the view. # return view(request, *args, **kwargs) # They are not logged in. See if they provided login credentials # if 'HTTP_AUTHORIZATION' in request.META: auth = request.META['HTTP_AUTHORIZATION'].split() if len(auth) == 2: # NOTE: We are only support basic authentication for now. # if auth[0].lower() == "basic": uname, passwd = base64.b64decode(auth[1]).split(':') email_user = User.objects.filter(email=uname) if not email_user: username = uname else: username = email_user[0].username user = authenticate(username=username, password=passwd) if user is not None: if user.is_active: login(request, user) request.user = user return view(request, *args, **kwargs) # Either they did not provide an authorization header or # something in the authorization attempt failed. Send a 401 # back to them to ask them to authenticate. # response = HttpResponse() response.status_code = 401 response['WWW-Authenticate'] = 'Basic realm="%s"' % realm return response ############################################################################# # def logged_in_or_basicauth(realm = ""): """ A simple decorator that requires a user to be logged in. If they are not logged in the request is examined for a 'authorization' header. If the header is present it is tested for basic authentication and the user is logged in with the provided credentials. If the header is not present a http 401 is sent back to the requestor to provide credentials. The purpose of this is that in several django projects I have needed several specific views that need to support basic authentication, yet the web site as a whole used django's provided authentication. The uses for this are for urls that are access programmatically such as by rss feed readers, yet the view requires a user to be logged in. Many rss readers support supplying the authentication credentials via http basic auth (and they do NOT support a redirect to a form where they post a username/password.) Use is simple: @logged_in_or_basicauth def your_view: ... You can provide the name of the realm to ask for authentication within. """ def view_decorator(func): def wrapper(request, *args, **kwargs): return view_or_basicauth(func, request, lambda u: u.is_authenticated(), realm, *args, **kwargs) return wrapper return view_decorator ############################################################################# # def has_perm_or_basicauth(perm, realm = ""): """ This is similar to the above decorator 'logged_in_or_basicauth' except that it requires the logged in user to have a specific permission. Use: @logged_in_or_basicauth('asforums.view_forumcollection') def your_view: ... """ def view_decorator(func): def wrapper(request, *args, **kwargs): return view_or_basicauth(func, request, lambda u: u.has_perm(perm), realm, *args, **kwargs) return wrapper return view_decorator |
You can use it in the view like this
1 2 3 4 5 | from httpauth import * @logged_in_or_basicauth() def fu(request,type): pass |
So this is dead simple and allows you to use simple HTTP authentication for your views. For any more help on this catch me at me@dipankar.name.
[...] So this is dead simple and allows you to use simple HTTP authentication for your views. Article from here. [...]
Nifty. Thanks for sharing.
There is obviously a lot to learn. There are some good points here.
-Robert Shumake Paul Nicoletti
Thanks for your post. I am new at python and this is a big help.
Hey Jackie, Glad i could be of any help !
Very useful. This should be added to the distribution, I’ve been disappointed at Django’s apparent lack of plug and play basic auth in the frontend.
Very good! This should be already inside the Django trunk! Thanks for sharing!
Ah, this is
http://djangosnippets.org/snippets/243/
so it can be reused:
http://djangosnippets.org/about/tos/