Django-RESTful Api之认证和权限
问题
- 没有认证和权限功能,任何资源都可以被任意用户随意修改,所以增加认证和权限功能
- student与其创建者相互关联
- 只有经过身份验证(登陆)的用户才可以创建student
- 只有创建student的用户才可以对其进行更新和删除
- 未经验证(游客)用户只能对数据进行访问(获取)的功能
给学生增加所有者字段
1 | owner = models.ForeignKey('auth.User', related_name='students') |
重新生成表
- 删除数据库、删除迁移文件、重新创建数据库、重新生成迁移文件、执行迁移、将班级数据插入
创建几个用户
1 | python manage.py createsuperuser |
在serializers.py文件中给User添加序列化类
1 | from rest_framework import serializers |
增加用户的接口
-
路由:
1
2
3
4
5
6
7
8
9
10
11
12
13from django.conf.urls import url
from myApp import views
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
url(r'^students/$', views.StudentsList.as_view()),
url(r'^students/(?P<pk>\d+)', views.StudentDetail.as_view()),
# 用户
url(r'^users/$', views.UsersList.as_view()),
url(r'^users/(?P<pk>\d+)', views.UserDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns) -
视图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14from myApp.models import Student, Grade
from myApp.serializers import StudentSerializer, UserSerializer
from rest_framework import generics
from django.contrib.auth.models import User
class UsersList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
把Student和User关联
-
**概述:**此时还不能把Student和User关联起来,因为在使用的时候User的数据时通过request传入的,而不是以序列化传递过来的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15from myApp.models import Student, Grade
from myApp.serializers import StudentSerializer, UserSerializer
from rest_framework import generics
from django.contrib.auth.models import User
from rest_framework import permissions
class StudentsList(generics.ListCreateAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
# 让用户通过POST请求创建一个新的student时,在保存对象数据时,会把request中的user赋值给student的owner属性
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
在显示学生时还需要显示学生属于哪个用户,可以选择展示
1 | # 只能序列化Student模型对象 |
添加权限
1 | from myApp.models import Student, Grade |
为可浏览的API添加登陆功能
-
在工程目录下的同工程相同名字的目录下的
urls.py
中添加如下代码1
2
3
4
5
6
7
8
9
10
11from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('myApp.urls')),
]
urlpatterns += [
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
添加对象权限
-
要实现让所有的student可以被所有人访问,但是每个student只能被其创建者操作。需要自定义权限,使每个学生只能被他的创建者操作。在
myApp
目录下创建permissions.py
-
自定义权限:
1
2
3
4
5
6
7
8from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user -
添加自定义权限:
1
2
3
4
5
6
7
8from myApp.permissions import IsOwnerOrReadOnly
class StudentDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
# 只有所有者用户才能删除、修改,其他用户只能查询
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)
API授权
- 现在没有使用authentication类,所以项目目前还是使用默认的SessionAuthentication和BaseAuthentication
- 在浏览器访问API的时候,浏览器会存储会话信息
- 如果通过其他方式操作API,我们必须在每次发送请求的时候添加授权信息,就是添加用户名和密,否则会报错
1
http://user1:sunck1999@127.0.0.1:8000/students/1