本文主要介绍基于token的用户跟踪,以及使用DRF创建REST风格的数据接口的方法。在设计和开发Web应用程序时,我们应该优先考虑基于token的用户跟踪方案。本文将会从什么是基于token的用户跟踪,为什么要使用它以及如何实现它这三个方面来详细介绍。
基于token的用户跟踪
基于token的用户跟踪是一种无状态的用户身份验证方式。在登录时,服务器会生成一个token,这个token被用来代替sessionID,这样服务器才能够判断用户的身份并授权用户访问相应的资源。相比于基于session的用户跟踪,基于token的用户跟踪具有更加灵活和可扩展的特点,尤其适用于前后端分离的Web应用程序。
基于token的用户跟踪的优点:
- 无状态:token包含了用户的所有信息,所以服务器无需存储用户信息,从而减轻了服务器的存储压力。
- 灵活和可扩展:可以在token中加入任意的信息,从而满足不同应用程序的需求。
- 安全性高:token的加密方式可以使用非对称加密方式,这样可以避免黑客攻击。
基于token的用户跟踪的缺点:
- 安全性问题:如果token丢失或被盗,黑客可以获取用户的所有信息。
- token长度:token的长度相对较长,因此在网络传输过程中会占用较大的带宽。
为什么要使用基于token的用户跟踪
基于token的用户跟踪相比于基于session的用户跟踪具有很多优点,尤其适用于前后端分离的Web应用程序。在前后端分离的Web应用程序中,前端负责渲染数据和展示页面,后端则负责提供数据接口。如果使用基于session的用户跟踪,会增加服务器的存储压力,而且session是有状态的,不符合前后端分离的设计理念。因此,使用基于token的用户跟踪是更好的选择。此外,基于token的用户跟踪还可以适用于多个不同的应用程序,因为每个应用程序的token都是独立的。
如何实现基于token的用户跟踪
实现基于token的用户跟踪需要以下几个步骤:
- 用户登录时,服务器生成token并返回给客户端。
- 客户端在每次请求时将token作为请求头或请求参数发送给服务器。
- 服务器根据token判断用户的身份并授权用户访问相应的资源。
在Django Rest Framework中,可以使用JWT(JSON Web Tokens)来实现基于token的用户跟踪。JWT是一种基于JSON的开放标准,用于在网络应用间传递声明。JWT由三部分组成:Header、Payload和Signature。Header包含了加密算法和类型信息,Payload包含了声明信息,Signature则是对Header和Payload进行签名的结果。
使用JWT实现基于token的用户跟踪的步骤:
- 安装
djangorestframework-jwt
包:在终端中输入pip install djangorestframework-jwt
。 - 在Django配置文件中配置JWT:在
settings.py
文件中添加以下代码:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
JWT_AUTH = {
'JWT_SECRET_KEY': SECRET_KEY,
'JWT_ALGORITHM': 'HS256',
'JWT_VERIFY': True,
'JWT_VERIFY_EXPIRATION': True,
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
'JWT_ALLOW_REFRESH': True,
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=30),
'JWT_AUTH_HEADER_PREFIX': 'Bearer',
}
- 编写登录视图函数:在视图函数中使用
jwt_encode_handler
函数生成token并返回给客户端。
from rest_framework_jwt.utils import jwt_encode_handler, jwt_payload_handler
def login(request):
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return JsonResponse({'token': token})
else:
return JsonResponse({'error': '用户名或密码错误'})
- 编写装饰器:在需要验证token的视图函数中使用装饰器进行验证。
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated
class MyView(APIView):
permission_classes = [IsAuthenticated]
authentication_classes = [JSONWebTokenAuthentication]
def get(self, request):
...
至此,我们已经完成了基于token的用户跟踪的实现,接下来我们将介绍如何使用DRF创建REST风格的数据接口。
使用DRF创建REST风格的数据接口
DRF是一个强大的框架,可以帮助我们快速创建REST风格的数据接口。使用DRF创建REST风格的数据接口可以通过CBV(基于类的视图)的方式,也可以通过继承ModelViewSet的方式。使用CBV创建数据接口的特点是代码简单,开发效率高,但是没有FBV(基于函数的视图)灵活,因为使用FBV的方式,数据接口对应的视图函数执行什么样的代码以及返回什么的数据是高度可定制的。使用ModelViewSet继承方式可以快速实现对POST、GET、PUT、PATCH、DELETE请求的支持。
使用CBV
使用CBV创建数据接口的方式非常简单,只需要声明如何获取数据以及如何序列化数据即可。以定制学科的数据接口为例。
继承APIView的子类
在polls/views.py
中去掉show_subjects
视图函数,添加一个名为SubjectView
的类,该类继承自ListAPIView
,ListAPIView
能接收GET请求,它封装了获取数据列表并返回JSON数据的get
方法。
from rest_framework.generics import ListAPIView
class SubjectView(ListAPIView):
queryset = Subject.objects.all()
serializer_class = SubjectSerializer
由于SubjectView
的父类ListAPIView
已经实现了get
方法来处理获取学科列表的GET请求,所以我们只需要声明如何获取学科数据以及如何序列化学科数据,前者用queryset
属性指定,后者用serializer_class
属性指定。要使用上面的SubjectView
,需要修改urls.py
文件。
继承ModelViewSet
使用ModelViewSet继承方式可以快速实现对POST、GET、PUT、PATCH、DELETE请求的支持。
from rest_framework.viewsets import ModelViewSet
class SubjectViewSet(ModelViewSet):
queryset = Subject.objects.all()
serializer_class = SubjectSerializer
使用ModelViewSet
的父类中已经实现了对POST、GET、PUT、PATCH、DELETE请求的支持,我们只需要指定如何获取到数据以及如何序列化数据即可。要使用上面的SubjectViewSet
,需要在urls.py
文件中进行URL映射。
数据分页
使用分页展示数据的方式,可以通过指定页码(或类似于页码的标识)和页面大小(一次加载多少条数据)来获取不同的数据。使用DRF时,可以在Django配置文件中修改REST_FRAMEWORK
并配置默认的分页类和页面大小来实现分页。除了PageNumberPagination
分页器之外,DRF还提供了LimitOffsetPagination
和CursorPagination
分页器,其中CursorPagination
可以避免使用页码分页时暴露网站的数据体量。
数据筛选
使用django-filter
可以实现对数据的筛选,可以通过为视图类配置filter-backends
属性并指定使用DjangoFilterBackend
来支持数据筛选。
以上就是本文对基于token的用户跟踪和使用DRF创建REST风格的数据接口的介绍和讲解。