#100DaysOfWeb in Python Transcripts
Chapter: Days 69-72: Django REST Framework
Lecture: Django REST permissions: authentication and authorization
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.