高级功能(认证&权限&分页)

认证Authentication

认证

1.概念

身份验证是将传入请求与一组标识凭据(例如,请求来自的用户或与其进行签名的令牌)相关联的机制。然后,权限限制策略可以使用这些凭据来确定是否应允许该请求。

身份验证本身不会允许或不允许传入的请求,它只会标识发出请求的凭据。

认证管理一般和权限管理配合使用。

2.认证方式

此身份验证方案使用HTTP基本身份验证,该身份针对用户的用户名和密码进行了签名。基本身份验证通常仅适用于测试

如果成功通过身份验证request.user将是DjangoUser实例。

未经授权的身份验证的响应将被拒绝 HTTP 401 Unauthorized

此身份验证方案使用Django的默认会话后端进行身份验证。会话身份验证适用于在与您的网站相同的会话上下文中运行的AJAX客户端

如果成功通过身份验证request.user将是DjangoUser实例。

未经授权的身份验证的响应将被拒绝HTTP 403 Forbidden

此身份验证方案使用简单的基于令牌的HTTP身份验证方案。令牌认证适用于客户端-服务器设置,例如本机台式机和移动客户端

为了使客户端进行身份验证,令牌密钥应包含在AuthorizationHTTP标头中。密钥应以字符串文字“ Token”作为前缀,并用空格分隔两个字符串。例如:

1
Authorization:Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

认证失败会有两种可能的返回值:

  • 401 Unauthorized 未认证
  • 403 Permission Denied 权限被禁止

3.认证全局设置

可以在配置文件中配置全局默认的认证方案

1
2
3
4
5
6
REST_FRAMEWORK = {
# 默认的认证列表: session
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', # session认证
)
}

因为 认证一般都是和权限配合使用,当我们不设置权限时,是没有任何效果的。为了让大家看到最佳效果,我们额外添加一条配置信息。配置信息的意思是 只有认证登录用户才可以访问视图

1
2
3
4
5
6
7
8
9
10
REST_FRAMEWORK = {
# 默认的认证列表: session
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
],
# 默认的权限列表: 只有登录用户才可以访问
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}

添加了权限配置之后,会出现如下响应

我们可以通过创建一个超级管理员,登录后台,来创建session信息

1.创建一个超级用户

2.登录后台 http://127.0.0.1:8000/admin/login/?next=/admin/

3.登录成功生成session

登录成功之后,再次刷新页面,就可以访问了

4.认证指定视图设置

也可以在每个视图中通过设置authentication_classess属性来设置

1
2
3
4
5
6
7
8
9
10
11
12
from book.models import BookInfo
from book.serializers import BookInfoModelSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.authentication import TokenAuthentication


class BookModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer

#单个视图,设置单独认证方式
authentication_classes = [TokenAuthentication]

权限Permissions

文档

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。

  • 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
  • 在通过get_object()获取具体对象时,会进行对象访问权限的判断

1.提供的权限

  • AllowAny 允许所有用户
  • IsAuthenticated 仅通过认证的用户
  • IsAdminUser 仅管理员用户
  • IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取

2.使用

可以在配置文件中设置默认的权限管理类,如

1
2
3
4
5
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}

如果未指明,则采用如下默认配置

1
2
3
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)

也可以在具体的视图中通过permission_classes属性来设置,如

1
2
3
4
5
6
7
8
9
10
11
from book.models import BookInfo
from book.serializers import BookInfoModelSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.authentication import SessionAuthentication

class BookModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer

#单个视图,设置单独认证方式
authentication_classes = [SessionAuthentication]

3.指定视图设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from book.models import BookInfo
from book.serializers import BookInfoModelSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import AllowAny

class BookModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer

#单个视图,设置单独认证方式
authentication_classes = [SessionAuthentication]
#设置单独的权限
permission_classes = [AllowAny]

分页Pagination

文档

REST framework提供了分页的支持。

Mysql查询分页语句:从索引第4开始,获取5条数据。

1
SELECT * FROM tb_item_bank limit 3,5;

我们可以在配置文件中设置全局的分页方式,如:

1
2
3
4
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100 # 每页数目
}

也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_clas属性来指明。

1
2
3
4
5
6
7
8
class LargeResultsSetPagination(PageNumberPagination):
page_size = 1000
page_size_query_param = 'page_size'
max_page_size = 10000
class BookDetailView(RetrieveAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
pagination_class = LargeResultsSetPagination

可选分页器

1)LimitOffsetPagination

前端访问网址形式:

1
GET http://api.example.org/books/?limit=100&offset=400

可以在子类中定义的属性:

  • default_limit 默认限制,默认值与PAGE_SIZE设置一致
  • limit_query_param limit参数名,默认’limit’
  • offset_query_param offset参数名,默认’offset’
  • max_limit 最大limit限制,默认None
1
2
3
4
5
6
7
8
9
10
11
from book.models import BookInfo
from book.serializers import BookInfoModelSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.pagination import LimitOffsetPagination

class BookModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
#分页类
pagination_class = LimitOffsetPagination
# http://127.0.0.1:8000/books/?limit=2&offset=4

2)PageNumberPagination

前端访问网址形式:

1
GET  http://api.example.org/books/?page=4

可以在子类中定义的属性:

  • page_size 每页数目
  • page_query_param 前端发送的页数关键字名,默认为”page”
  • page_size_query_param 前端发送的每页数目关键字名,默认为None
  • max_page_size 前端最多能设置的每页数量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from book.models import BookInfo
from book.serializers import BookInfoModelSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.pagination import PageNumberPagination
#自定义分页类
class PageNum(PageNumberPagination):
page_size = 2 # 默认每页返回的条数
page_size_query_param = 'pagesize' # url中设置 page_size的键,默认为page_size
max_page_size = 10 # 每页返回的最大条数


class BookModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
#使用自定义分页类
pagination_class = PageNum



#http://127.0.0.1:8000/books/?page=1&pagesize=4

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!