程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Django API development: permission management of blog system

編輯:Python

introduction

Security is an important part of any website , But for the Web API It is crucial for us . at present , our Blog API Allow anyone full access . No restrictions ; Any user can do anything extremely dangerous . for example , Anonymous users can create , read , Update or delete any blog posts . They didn't even create one ! obviously , We don't want to do this .


Django REST Framework Comes with some ready-made permission settings , We can use these settings to protect our API. These can be applied at the project level , View level or any individual model level .


In this chapter , We'll add a new user and try multiple permission settings . then , We will create our own custom permissions , So that only the author of the blog post can update or delete it .

Add a new user

First create a second user . such , We can switch between two user accounts to test our permission settings .


Browse to http://127.0.0.1:8000/admin/ The administrator of . And then click “ user ” Lateral “ + add to ”.


Enter the user name and password of the new user , And then click “ preservation ” Button . I chose the user name here testuser.




The next screen is “ Administrator user changes ” page . I've called my users testuser, Here I can add other information contained in the default user model , For example, name , surname , Email address, etc . But for us , None of this is necessary : We just need user name and password Used to detect .




Scroll down to the bottom of this page , And then click “ preservation ” Button . It will be redirected back to http://127.0.0.1:8000/admin/auth/user/ Main user page .




We can see that there are two users in the list .

stay browsable API Add login function

In the future , Whenever you want to switch between user accounts , We all need to jump to Django Administrators , Exit an account , Then log in to another account . Every time . And switch back to our API Endpoint .


This is a common situation ,Django REST Framework Have single line settings to add login and log out directly to browsable API In itself . We will implement it immediately .


At the project level urls.py In file , Add a containing rest_framework.urls The new URL route . What is puzzling is , The actual route specified can be anything we want ; It is important to rest_framework.urls Contained somewhere . We will use api-auth route , Because it matches the official documents , But we can easily use anything we want , And all functions will remain the same .


# blog_project/urls.pyfrom django.contrib import admin from django.urls import include, pathurlpatterns = [ path('admin/', admin.site.urls), path('api/v1/', include('posts.urls')), path('api-auth/', include('rest_framework.urls')), # new]


Now? , visit http://127.0.0.1:8000/api/v1/ Browsable on API. There is a slight change : Next to the user name in the upper right corner is a downward arrow .




Since we have logged in with the super user account at this time ( For me, yes wsv ), Therefore, the name... Will be displayed . Click on the link , Then it displays with “ Cancellation ” The drop-down menu for . Click on it .




The link in the upper right corner is now changed to “ Sign in ”. therefore , Please click this button .




We were redirected to Django REST Framework The login page . Use your test user account here .




Last , It will redirect to the main API page , There's... In the upper right corner testuser.




Last , Write off our testuser account .




You should see again in the upper right corner “Log in” link .

AllowAny

At present , Any anonymous unauthorized user can access our PostList Endpoint . The reason why I know this , Because we haven't logged in yet , You can also see our individual blog posts . What's worse is , Anyone has the right to create , edit , Update or delete posts !


On the details page http://127.0.0.1:8000/api/v1/1/ On , This information is also visible , Any random user can update or delete existing blog posts .




The reason why you can still see “ Publish list ” Endpoints and “ Detailed list ” endpoints , Because we were in settings.py Set the project level permission of the project to AllowAny. A brief reminder , It looks something like this :


# blog_project/settings.pyREST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ]}

View layer permissions

What we want now is to API Access is restricted to authenticated users . We can do this in multiple places - Project level , View level or object level - But because we only have two views at present , So let's start there , And add permissions for each view .


In your posts/views.py In file , from Django REST Import permissions at the top of the frame , Then add one... To each view permission_classes Field .


# posts/views.pyfrom rest_framework import generics, permissions # newfrom .models import Postfrom .serializers import PostSerializerclass PostList(generics.ListCreateAPIView): permission_classes = (permissions.IsAuthenticated,) # new queryset = Post.objects.all() serializer_class = PostSerializer class PostDetail(generics.RetrieveUpdateDestroyAPIView): permission_classes = (permissions.IsAuthenticated,) # new queryset = Post.objects.all() serializer_class = PostSerializer


This is what we need . adopt http://127.0.0.1:8000/api/v1/ Refresh browsable API. See what happened !




We no longer see our “ List of Posts ” page . In its place , Because we haven't logged in yet , So you will receive unfriendly HTTP 403 Prohibition status code . Because we have no authority , So you can browse API There are no tables in the to edit data .




therefore , At present, only logged in users can view our API. If you use super user or testuser Account login again , You can visit API Endpoint .


however , Please consider following API What happens with the growth of complexity . In the future, we may have more views and destinations . If we're going to be in the whole API Set the same permission settings in , Add a dedicated... To each view permission_class It seems to be repeated .


It's best to change permissions only once at the project level , Instead of making a change to every view , Would it be better ?

Project level permissions

here , You should nod . It is easier to set strict permission policies at the project level and relax them as needed at the view level , A safer way . This is what we have to do .


Fortunately, ,Django REST Framework along with Attached are many built-in project level permission settings that we can use , Include :


  • AllowAny- Any authenticated user has full access

  • IsAuthenticated- Only authenticated registered users can access

  • IsAdminUser- Only administrators / Super users have access to

  • IsAuthenticatedOrReadOnly- Unauthorized users can view any page , However, you can only see that authenticated users have write access , Edit or delete permissions


To implement any of these four settings , All need more DEFAULT_PERMISSION_CLASSES Set and refresh our Web browser . nothing more !


Let's switch to IsAuthenticated , In this way, only authenticated or logged in users can view API.


to update blog_project/settings.py, as follows :


# blog_project/settings.pyREST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', # new ]}


Now back to views.py file , And delete the permission change we just made .


# posts/views.pyfrom rest_framework import genericsfrom .models import Postfrom .serializers import PostSerializerclass PostList(generics.ListCreateAPIView): queryset = Post.objects.all() serializer_class = PostSerializer class PostDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Post.objects.all() serializer_class = PostSerializer


If you refresh “ Publish list ” and “ Detailed list ” API page , You will still see the same 403 The status code . Now? , We require all users to authenticate first , Then we can visit API, But we can always make other view level changes as needed .

Custom permissions

It's time to get our first custom permission . As our brief review now : We have two users ,testuser And super user accounts . There is a blog post in our database , Created by super user .


We only hope that the author of a specific blog post can edit or delete it ; otherwise , Blog posts should be read-only . therefore , The superuser account should have full access to a single blog instance CRUD Access right , And regular users testuser There should be no .


Use Control + c Stop the local server , And create a new one in our post application permissions.py file .


(blogapi) $ touch posts/permissions.py


In the internal ,Django REST Framework Depend on BasePermission class , All other permission classes are from this BasePermission Class inheritance . This means things like AllowAny,IsAuthenticated Built in permission settings such as will extend it . This is a Github Available on Actual source code :


class BasePermission(object): """ A base class from which all permission classes should inherit. """ def has_permission(self, request, view): """ Return `True` if permission is granted, `False` otherwise. """ return True def has_object_permission(self, request, view, obj): """ Return `True` if permission is granted, `False` otherwise. """ return True


To create your own custom permissions , We will cover has_object_permission Method . say concretely , We want to allow read-only for all requests , But for any write request ( Edit or delete, for example ), The author must be the same as the currently logged in user .


This is ours posts / permissions.py The content of the document .


# posts/permissions.pyfrom rest_framework import permissionsclass IsAuthorOrReadOnly(permissions.BasePermission): def has_object_permission(self, request, view, obj): # Read-only permissions are allowed for any request if request.method in permissions.SAFE_METHODS: return True # Write permissions are only allowed to the author of a post return obj.author == request.user


We import permissions at the top , Then create a custom class IsAuthorOrReadOnly, This class extends BasePermission. then , We cover has_object_permission. If the request contains SAFE_METHODS It contains HTTP Verb ( contain GET,OPTIONS and HEAD tuples ), Then the request is read-only , And grant permission .


otherwise , The request is for some type of write , This means that you need to update API resources , To create , Delete or edit functions . under these circumstances , Let's check the author of the object of discussion ( Our blog posts obj.author) Whether or not to make a request request.user The user matches .


go back to views.py In file , We should import IsAuthorOrReadOnly, Then we can add PostDetail Of ``permission_classes`.


# posts/views.pyfrom rest_framework import genericsfrom .models import Postfrom .permissions import IsAuthorOrReadOnly # new from .serializers import PostSerializerclass PostList(generics.ListCreateAPIView): queryset = Post.objects.all() serializer_class = PostSerializerclass PostDetail(generics.RetrieveUpdateDestroyAPIView): permission_classes = (IsAuthorOrReadOnly,) # new queryset = Post.objects.all() serializer_class = PostSerializer


We finished . Let's test it out . Navigate to “ Post details ” page . Make sure you log in with the author superuser account of the post . Therefore, it will be visible in the upper right corner of the page .




however , If you log out and use testuser Account login , The page will change .




Because read-only permission is allowed , So we can view this page . however , Because of the custom IsAuthorOrReadOnly Permission class , We can't send any PUT or DELETE request .


Please note that , A generic view will only check object level permissions to get a view that retrieves a single model instance . If you need object level filtering on the list view ( For instance collection ), You have to go through Override the initial query set To filter .

summary

Setting the appropriate permissions is any API An important part of . As a general strategy , It is best to set strict project level permission policies , So that only authenticated users can view API. then , As needed in a specific API Easier access to view levels or custom permissions on endpoints .


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved