#100DaysOfWeb in Python Transcripts
Chapter: Days 69-72: Django REST Framework
Lecture: Django REST permissions: authentication and authorization
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
Just to recap, we have our Django REST API up and running. Supporting listing and supporting full CRUD by using the ListCreateAPIView
0:15
and the RetrieveUpdateDestroyAPIView. Now let's move on to permissions. And we have a big problem now.
0:23
As we saw in a previous video, when we logged out the quotes were still editable. Which is of course something you would never want.
0:31
So we're going to lock that down. First we're going to apply the IsAuthenticatedOrReadOnly setting in our settings.py. And that makes the quotes
0:42
read-only when logged out and editable when logged in. And secondly, we're going to protect the user's quotes to make them only editable
0:52
to the user that's logged in and is owning the quotes. So that will look something like this that when I'm logged in as pybites I can edit my own quote
1:02
but when I'm logged in as another user I cannot edit pybites' quotes. So first we look at authentication to make sure that nobody can edit stuff
1:11
when not logged in. And secondly, we make sure we have authorization that ensures that we grant access to objects to the right user.
1:21
All right, so let's write some code. Now first of all actually just to point out how great the documentation of the Django REST framework is
1:31
there's a whole chapter on permissions and it explains exactly the levels you can use. So actually, at first I was using IsAuthenticated
1:41
but that locks down the whole API and let me actually show that. So what we first want to do is go to settings and use the REST framework dictionary
1:51
where you can define project-wide settings. So I'm going to copy this and I will show you first what IsAuthenticated will look like.
2:10
If I refresh the page, I can not even look at quotes. So the whole API is now locked down. And it gives me a 403 saying
2:19
authentication credentials were not provided. But that's not really correct right? Because, we surely want to allow users to
2:28
look at quotes without editing them. And actually at the end of this page we see the different settings explained
2:36
so default is AllowAny and that was the reason that everything was editable, when I was not authenticated. Now we set it to IsAuthenticated
2:45
but that's kind of too strict. So it's best to go with IsAuthenticatedOrReadOnly in our case. And that will allow unauthorized users
2:54
to have access to "save methods" which are get head and options. So let's change this now. And now, I can actually look at the quotes
3:09
but I can not edit them. So that's the ideal setting for our API. I will log in again, I can of course edit the quotes.
3:18
Now the second thing is authorization. So now we're going to make a second user. And we're going to make sure that users can edit only their own quote.
3:28
So go to users, and you add a user. And let me go to the site. Log out pybites. Log in as the new user.
3:45
And that's cool, I cannot edit the quotes from pybites. So let me add a quote of myself. And I can only edit my own quote
4:02
at the frontend we implemented this well. Not so much in the API, because if I go to quote list, I go to my new quote
4:12
which I think is 33, 'cause I've been doing some adds and deletes before. So the primary key is at 33 now
4:18
I'm logged in as bob, I can edit my own quote. So that's good. But if I log in as pybites I can also edit that quote, and that's not good.
4:32
So we need to lock down the detail view to be editable only by the user that owns the quote. And the way you can do that is to write
4:39
your own custom permissions. And they actually provide an example here which we're going to use. And it's called IsOwnerOrReadOnly.
4:51
So we can, in our API app we can make a permissions file. And we can use this permission so we do have to import permissions
5:11
Let's customize this a bit. So if it's a save method like get head or options then I return true. I can always access that. However, if it's something
5:28
that potentially destroys it so if it's a request to edit the quote I'm going to match the user of the quote with the user that's making a request.
5:38
And here it's using owner but in our model that's actually called user. So we have to use... We have to match this field.
5:49
So the user field we define that as user. So we have to use the user attribute. So we match the user of the quote
5:58
with the user that's making the request. If those match, this results in true. Give access to added. Otherwise we don't.
6:07
Now the second thing we need to do is to reference this new permission in our view. So I'm going to import it, at the top.
6:21
And I'm going to use it in the detail view that has that update and destroy capability. So I want to lock this down.
6:30
And I'm going to define permission classes. Which is a pre-defined attribute. On the REST framework. And that requires a tuple
6:42
of the permission we just defined and that should be it. Let's try that out. And there you go. It's now locked down.
6:52
I'm not able to edit quotes of bob. But I'm able to edit my own stuff. Yeah. On the other hand if I log out and log in as bob
7:07
I'm not able to edit pybites' quote. But I'm able to edit my own quote. Perfect. So as we've seen, with very little code
7:16
we have been able to implement authentication. Supporting read-only access to locked out users. And also authorization to protect quotes from
7:25
being editable to users that do not own the quotes. And again, Django REST framework makes it very easy to set this up with
7:34
very little code. In the next video we're going to look at making beautiful documentation with the Django REST Swagger plugin.