Authorization in django webapp

Amar Savalagi
3 min readApr 12, 2018

--

In this blog I am trying to explain how django-project implements a common web application feature ‘authorization’. django packages authentication(i.e Identifying user uniquely by passwords) and authorization (i.e Allowing/denying user to access particular feature/url/action)into an inbulit app called ‘auth’.

When you think about authorization in webapp, it seems like really complex and worrisome. django-project comes along with well thought features and reusable pieces of codes. django takes the full advantage of OOPS concepts, by inheriting mixin in classes or decorating your functions, one can implement apparently super complex features like authorization almost with out having to writing a new line of code.

User Story:
Lets take an example of simple and most common case. We have two group of users, say “foo”and “bar”. When they login they need to be routed to say, url /dashboard_foo/ and /dashboard_bar/ respectively.

Permissions:
django-project built-in auth app, which contains three django model objects User ,Group and Permission. User andGroup have many2many connection with each other (that means many users can belong to one group and one user can belong to many groups). And also both Userand Grouphave many2many connection with Permission .

By default django creates three Permission objects for each model objects. That means , say you have model object Poll , then there would be permission objects add_poll, change_polland delete_poll .

Try this

Permission.objects.get(codename=add_<model_obejct_lowercase>)

Permission.objects.get(codename=add_poll)

Assigning permissions:
Using admin interface of django one can easily manage group, users and assign them permissions.

Actual gate keeping:
django being django, solves this whole authorization in pretty elegant way. In django every url pattern match is mapped with an callable (class/function).

Lets say url /foo_dashboard/ is rendered by function based view foo or by a class based view Foo . django authorizes these callable views by checking if request.useris authenticated and have specific permission before calling them. If the user is not authenticated or authorized it redirects to LOGIN_URL defined in settings.py

How do you do it?

For function based view ,use permission_requireddecorator. It takes in str argument 'appname.<permission_codename>'

from django.contrib.auth.decorators import permission_required@permission_required('appname.<permission_codename>')
def foo(request):
pass
# Example:
@permission_required('poll.add_poll')
def foo(request):
pass

For Class Based views

from django.contrib.auth.mixins import PermissionRequiredMixinclass Foo(PermissionRequiredMixin, View):
permission_required = 'appname.<permission_codename>'
pass
#Example:class Foo(PermissionRequiredMixin, View):
permission_required = 'poll.add_poll'
pass

More and More:
There are other mixin and decorator like LoginRequiredMixin and login_required respectively which can be used to authorize common urls like reset passwords. Here is the source code
django thus proves the rapid development by using reusable codes like mixins, decorator and abstract classes, that do magic in few lines of codes. If you find this interesting visit, APIMonk an django based project to automate API development, testing and deployment.

--

--