Knowing who someone is is just the first step. Now you need to make sure they have the ability to do the thing they want.
With this new auth method, 0:00 it's time to start thinking about permissions, also known as authorization. 0:02 Authentication is all about connecting some credentials to the incoming request. 0:06 The token you pass in the header maps to the user that has that token. 0:10 That authenticates the request if it's from another user. 0:14 Authorization though, is about ensuring that the user has permission 0:17 to do the action they want to do. 0:20 Like CRUD operations or even just accessing the API. 0:22 In REST framework, authorization or 0:26 permission checks will typically use the authentication information and a couple of 0:28 request properties to decide if the incoming request should be authorized. 0:32 This happens before your view's methods are ever evaluated. 0:36 If the user isn't authorized, 0:39 REST framework will return either a 403 Forbidden or a 401 Unauthorized, 0:41 depending on whether the user failed authentication or authorization. 0:45 Remember when I first started the project? 0:49 I set the default permission class to be IsAuthenticated or ReadOnly. 0:51 This permission means that you have to provide a real, valid user to perform any 0:55 action that involves creating, updating, or deleting data. 0:59 Anyone can read the data, though. 1:02 What other options do we have? 1:04 AllowAny is wide open and allows anyone to do as they please. 1:06 IsAuthenticated requires the user to be authenticated, 1:10 like by providing a valid token. 1:13 Once they're authenticated, they can do anything they want. 1:15 IsAdminUser will only allow access to 1:17 authenticated users that have been marked as is_staff. 1:20 And DjangoModelPermissions ties into Django's standard model permissions. 1:24 Authorization will only be granted to authenticated users who have 1:29 been assigned to the relevant model permissions. 1:31 That's a lot to take in. 1:34 So check the teacher's notes for 1:36 documentation on all of the different built in permissions classes. 1:37 What about setting permissions per view, though? 1:40 Let me show you how to protect a single specific view in workspaces. 1:43 So I've created a new user. 1:47 I want to show you a couple of things about him here. 1:49 So this is a test user and 1:52 they are active, they're not staff, they're not a super user. 1:56 But they do have one permission, which is that they can add a course. 2:00 So that's all they can do. 2:05 They can just add courses. 2:06 They can't add users, groups, anything like that. 2:07 They can't log in the admin, nothing. 2:09 All they can do is add a course. 2:12 So I've saved them and I've already created a token for 2:15 them, which I've put here into the readme. 2:17 So let's see about handling these permissions. 2:22 So I'm gonna hop back over here to views.py and 2:25 I need to add an import, so that I'll go here. 2:29 From rest_framework import permissions, 2:33 and I'm gonna focus on the Django model permissions class. 2:38 So like I said, I've already added the user with a single permission, so 2:42 I'm gonna take care of that, I'm gonna address that in my CourseViewSet. 2:45 So where's CourseViewSet? 2:51 Here's CourseViewSet. 2:52 All right, so queryset, serializers, OPQ, right? 2:52 So permission_classes and its tuple. 2:58 So permissions.DjangoModelPermissions. 3:03 All right, so what this specifies is that for this view set, 3:08 ignore the default permissions and care about Django model permissions. 3:13 So make sure that any users who are trying to do things inside this CourseViewSet, 3:19 they have the right permissions as far as Django is concerned. 3:24 Okay, and since that's a tuple, I could provide more if I wanted to, 3:27 they'd fall back, so on and so forth, right. 3:30 All right, let's go back over here to postman, postman holds on to your URLs, 3:33 as you can see, and also holds on to header and body content. 3:38 So I'm gonna make sure and 3:42 delete this authorization header, because I don't want that to hang out. 3:44 And on the body, I'm gonna make sure and 3:50 delete all of my body content, because I want to get rid of all of those. 3:52 Okay, so I wanna make sure the get still works. 3:57 And Authentication credentials were not provided, so all right, that didn't work. 4:00 I got a 401, it's unauthorized, because the Django model permissions, 4:06 you have to have the add, the create, the view, whatever. 4:09 All right, so, cool. 4:12 Don't have that permission, so I can't just do that. 4:13 By the way, let me show you real quick the permissions here. 4:16 If I come down here to user permissions, let's just filter to course. 4:20 So you can see here this change, delete, add? 4:25 You have to have change in order to be able to view one. 4:27 So I'm not authed, so my unauthenticated user does not have 4:31 permission to view one, so all right. 4:36 So let's come back over here to Headers, and we'll put in Authorization 4:40 and Token, and then my new user's token there and I 4:46 will hit send, and yeah, it's the add, the add and the change both let you see them. 4:52 I've got the results back, which is cool. 4:57 I can create or I can view them, so that's cool. 5:00 All right, so now I want to try and create a new course. 5:04 So let's go over here and change this to POST again. 5:09 Go back to Body, form-data. 5:13 Title is gonna be Django Basics. 5:16 And my other key here is url 5:21 https://teamtreehouse.com/library/django-- basics. 5:23 All right, now I have the create, the add permission, right. 5:30 So I should be able to do this. 5:36 So if I hit send, great, I got back a 201 and django-basics now exists. 5:37 All right, so cool, I'm super glad that works. 5:43 This user shouldn't be able to delete anything, so let's make sure. 5:47 So I'm gonna go to POST, I'm gonna go to delete, and 5:49 I wanna try to delete number five, which is the one I just created, right. 5:52 And I can get rid of this body data. 5:58 That's cool, okay, my header is still in there, my authentication header. 6:01 I'm gonna try and delete the one that I just created. 6:05 Send, and I don't have permission to perform this action. 6:09 So that's great. 6:12 I only gave them the add permission. 6:12 So they can add new ones, 6:15 they can't update, they can't delete, nothing like that. 6:16 All they can do is view them or add new ones. 6:19 Awesome, if I was using my super user's credentials, 6:21 I'd be able to do all of the stuff because they're marked as the super user, 6:25 they automatically have all permissions. 6:28 So what if I'm faced with a permissions check that isn't built in to REST 6:30 framework? 6:34 What if I only wanted to apply a permission check to a specific action? 6:34 Situations like this come up all the time. 6:39 I don't want regular users deleting courses, of course. 6:41 I only want super users to have that ability. 6:45 How do I handle that? 6:47 So first of all, I need to create my own permission class to perform this check. 6:49 So I'm gonna do it right up here above the CourseViewSet. 6:53 You probably would do this in a permissions.py or 6:58 something like that if you were doing this on your own and you had more than one. 7:00 So, whatever. 7:03 Okay, so class IsSuperUser. 7:05 And this will extend the permissions.BasePermission class. 7:08 Pretty much all of your permissions are going to extend this one. 7:14 And the thing that we override here is has_permission, 7:17 and self, request and view. 7:22 Those are the arguments that come in. 7:25 So this way I can check the = request and make sure it's of a particular type, 7:27 I can check the request user, I can do all this kind of stuff. 7:31 So if request.method = delete and 7:34 request.user.is_superuser, then we're gonna return true, 7:39 otherwise we're gonna return false. 7:46 I could actually write this a little shorter and 7:51 I could just return request.method = delete and 7:53 request.user.is_superuser and it checks to make sure those are both true, 7:55 but it's fine to make it a little bit longer. 7:59 And now I need to apply this class to my CourseViewSet class. 8:03 So this is a tuple, let's add in a new one. 8:09 And I want to put my special one, IsSuperUser, 8:12 above the DjangoModelPermissions one, because I want that one checked first. 8:15 So if it is a delete and they aren't a super user, 8:20 we just immediately kick it out, we don't ever even go to DjangoModelPermissions. 8:23 Cool, right? 8:27 I want to change my user here. 8:28 And I'm gonna give them the ability to delete a course. 8:31 I'm actually gonna give them, they can change a course too, why not? 8:33 All right, so I'll save and continue editing so that it just comes right back. 8:36 All right, now this user has the ability to delete courses, right? 8:40 But they're still not a super user. 8:45 So let's see if this works. 8:47 So they can delete, hit Send, 8:49 they still cannot delete that one because they're not a super user. 8:52 If, however, I go to my user, 8:57 this is why it's really handy having those tokens saved somewhere. 8:59 Come over here to Headers, change that token, hit Send, and it's gone, all right? 9:05 And if I was to do a get on courses, I should only see four of them. 9:13 How does a super user not have permission to perform that action? 9:19 You know what? 9:25 I think I need to change my thing here. 9:25 So let's do this. 9:33 There we go. 9:38 Okay, so if it's delete then we come inside here. 9:39 That should fix it. 9:42 What is that doing? 9:50 Let's try that one. 10:04 Cool, there we go. 10:06 And just to make sure, I will go back over to the other user. 10:09 And try to delete one of these. 10:21 Let's try to delete number four. 10:25 Cool, so the users have to have permission or be a super user. 10:29 They can't just delete things just because they want to. 10:33 It is possible to check permissions at the object level 10:37 with the DjangoObjectPermissions class. 10:39 But this requires the use of an object level permissions package 10:42 such django-guardian. 10:45 Check the teacher's notes section for links to the permissions documentation and 10:46 the django-guardian package. 10:50 Since I haven't hit my rate limit yet, 10:52 I'll see you in the next video to take a look at throttling. 10:54
You need to sign up for Treehouse in order to download course files.Sign up