> 文章列表 > 6、DRF实战总结:认证及使用Token认证,代码示例详解(附源码)

6、DRF实战总结:认证及使用Token认证,代码示例详解(附源码)

引言
在现代的Web应用开发中,安全性是一个至关重要的考虑因素。特别是在前后端分离的架构模式下,选择合适的认证机制对于保护用户数据和应用安全至关重要。本文将深入探讨如何在DRF(Django REST Framework)中使用基于Token的身份验证,以及这种认证方式相比传统的基于会话的身份验证(如Session Authentication)的优点和适用场景。

相关问题
1. 为何选择Token认证?
在前后端分离的开发模式中,传统基于会话的身份验证方式(如Session Authentication)需要依赖服务器的会话存储,这可能不便于跨域认证管理。而Token认证,作为JWT(JSON Web Tokens)标准的一部分,允许客户端存储和验证JWT,这更加灵活且易于管理。

2. DRF中的Token认证是如何工作的?
DRF提供了TokenAuthentication类,它允许客户端通过在请求中包含有效的JSON Web Token来进行身份验证。服务器在用户成功登录后生成Token,并将其返回给客户端,客户端随后使用这个Token进行随后的请求。

相关答案
- 如何设置Token认证?
- 在DRF中使用Token认证非常简单,只需在设置文件中将TokenAuthentication添加到定义的身份验证类列表中即可。
- 示例代码:
`python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
# ...其他认证方案
],
}
`

- 如何在视图中使用Token认证?
- 使用基于类的视图(CBV)时,可以通过在视图的authentication_classes属性中添加TokenAuthentication来使用它。
- 例如:
`python
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.mixins import CreateModelMixin, ListModelMixin
from rest_framework.viewsets import GenericViewSet

class ArticleViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
`

- Token认证与其他认证方案相比的优势是什么?
- 灵活性:Token可以在任何地方使用,不受会话状态的限制。
- 安全性:JWT包含经过签名的信息,可以有效防止数据篡改。
- 扩展性:通过在客户端保存Token,可以支持更多类型的客户端应用,如移动应用或浏览器扩展。

通过本文的介绍,现在你不仅了解了如何在DRF中实现Token认证,还知道了这种认证方式相比传统方法的优越性。在实际开发中,应根据实际需求和场景选择合适的认证方案,以确保应用的安全性和用户体验。

6、DRF实战总结:认证及使用Token认证,代码示例详解(附源码)

前面详细介绍了如何在DRF中使用权限以及如何自定义权限,实现了只有经过身份验证的用户可以创建文章并且只有文章的所有者可以编辑和删除文章。然而前篇文章中使用了Django默认的基于session的认证方式,实际前后端分离开发项目中后台更多采用的是token(令牌认证)。

本文将详细介绍认证(authentication)的本质,如何在DRF中使用自带的几种不同的认证方案,并重点介绍如何使用DRF自带的token认证。

JSON Web Token是一种更新的使用token进行身份认证的标准。与内置的TokenAuthentication方案不同,JWT身份验证不需要使用数据库来验证令牌, 而且可以轻松设置token失效期。Django中可以通过djangorestframework-simplejwt 这个第三方包轻松实现JWT认证,将在下篇文章中进行详细介绍。

认证(Authentication)

身份验证是将传入的请求对象(request)与一组标识凭据(例如请求来自用户或其签名的令牌token)相关联的机制。REST framework 提供了一些开箱即用的身份验证方案,并且还允许实现自定义方案。

DRF的每个认证方案实际上是一个类。可以在视图中使用一个或多个认证方案类。REST framework将尝试使用列表中的每个类进行身份验证,并使用成功完成验证的第一个类返回的元组设置 request.user request.auth

用户通过认证后request.user返回Django的User实例,否则返回AnonymousUser的实例。request.auth通常为None。如果使用token认证,request.auth可以包含认证过的token。

注:认证一般发生在权限校验之前。

REST framework自带的认证方案

Django REST Framework提供了如下几种认证方案:

  1. Session认证SessionAuthentication类:此认证方案使用Django的默认session后端进行身份验证。当客户端发送登录请求通过验证后,Django通过session将用户信息存储在服务器中保持用户的请求状态。Session身份验证适用于与网站在相同的Session环境中运行的AJAX客户端 (注:这也是Session认证的最大弊端)
  2. 基本认证BasicAuthentication类:此认证方案使用HTTP基本认证,针对用户的用户名和密码进行认证。使用这种方式后浏览器会跳出登录框让用户输入用户名和密码认证。基本认证通常只适用于测试。
  3. 远程认证RemoteUserAuthentication类:此认证方案为用户名不存在的用户自动创建用户实例。这个很少用,具体见文档。
  4. Token认证TokenAuthentication类:该认证方案是DRF提供的使用简单的基于Token的HTTP认证方案。当客户端发送登录请求时,服务器便会生成一个Token并将此Token返回给客户端,作为客户端进行请求的一个标识,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。后面会详细介绍如何使用这种认证方案。

注意:如果在生产环境下使用BasicAuthenticationTokenAuthentication认证,必须确保API仅在https可用。

DRF中使用自带认证方案

settings.py中设置默认的全局认证方案

# 设置默认的全局认证方案
# REST framework api的任何全局设置都保存 "REST_FRAMEWORK" 的配置中
REST_FRAMEWORK = {# Use Django's standard `django.contrib.auth` permissions,# or allow read-only access for unauthenticated users.'DEFAULT_PERMISSION_CLASSES': [# 'rest_framework.permissions.AllowAny',  # 默认无限制访问'rest_framework.authentication.BasicAuthentication','rest_framework.authentication.SessionAuthentication',]
}

基于类的视图(CBV)中使用


函数视图中使用

自定义认证方案

要实现自定义的认证方案,要继承BaseAuthentication类并且重写.authenticate(self, request)方法。如果认证成功,该方法应返回(user, auth)的二元元组,否则返回None

在某些情况下,可能不想返回None,而是希望从.authenticate()方法抛出AuthenticationFailed异常。

通常应该采取的方法是:

  1. 如果不尝试验证,返回None。还将检查任何其他正在使用的身份验证方案。
  2. 如果尝试验证但失败,则抛出AuthenticationFailed异常。无论任何权限检查,也不检查任何其他身份验证方案,立即返回错误响应。

也可以重写.authenticate_header(self, request)方法。如果实现该方法,则应返回一个字符串,该字符串将用作HTTP 401 Unauthorized响应中的WWW-Authenticate头的值。

如果.authenticate_header()方法未被重写,则认证方案将在未验证的请求被拒绝访问时返回