BaseAuthentication 类: django rest framework 通过 BaseAuthentication 实现认证功能 无论是自定义的认证类还是 rest framework 自带的认证类都应该继承 BaseAuthentication BaseAuthentication 中有两个方法 authenticate 和 authenticate_header, 其中 authenticate 方法必须实现 如果用户需要自定义认证方法则继承 BaseAuthentication 重写 authenticate 方法即可
?
?
models.py
from django.db import modelsclass UserInfo(models.Model): user_type_choices = ( (1, ‘普通用户‘), (2, ‘VPI‘), (3, ‘SVPI‘), ) user_type = models.IntegerField(choices=user_type_choices) username = models.CharField(max_length=32, unique=True) password = models.CharField(max_length=64)class UserToken(models.Model): user = models.OneToOneField(‘UserInfo‘, models.CASCADE) token = models.CharField(max_length=64)
?
?
app_dir/utils/auth.py????? # Create a Utils package in a directory similar to views.py, create a auth.py file in Utils, and place the authentication-related code in it
from rest_framework import exceptionsfrom rest_framework.authentication import BaseAuthenticationfrom app01 import models# 实现自定义的认证类class Authtication(BaseAuthentication): def authenticate(self, request): # 这儿的 request 对象不是 django 原生的 request 而是 rest_framework 内部进行封装过的 request # 使用 request._request 调用 django 原生的 request 对象 token = request._request.GET.get(‘token‘) # 检查用户的 token 是否合法 token_obj = models.UserToken.objects.filter(token=token).first() if not token_obj: # rest_framework 会在内部捕捉这个异常并返回给用户认证失败的信息 raise exceptions.AuthenticationFailed(‘用户认证失败‘) # 在 rest_framework 内部会将这两个字段赋值给request以供后续调用 return (token_obj.user, token_obj)
?
?
views.py
From django.http import jsonresponsefrom rest_framework.views import apiviewfrom app01.utils.auth Import Authticationimport hashlibimport time# generates token string def MD5 (user): CTime = str (time.time ()) m = Hashlib.md5 (b Ytes (user, encoding= ' utf-8 ')) m.update (bytes (ctime, encoding= ' Utf-8 ')) return m.hexdigest () # User Login class AUTHV Iew (Apiview): Def post (self, request): ret = {' Code ': +, ' msg ': None} try: user = Request._request. Post.get (' username ') pwd = request._request. Post.get (' password ') obj = models. UserInfo.objects.filter (Username=user, Password=pwd). First () if not obj: ret[' Code ' = 1001 ret[' msg '] = "username or password error" # Create token for logged-in user token = MD5 (user) #存在更新 does not exist to create models. UserToken.objects.updaTe_or_create (user=obj, defaults={' token ': token}) ret[' token '] = token except: ret[' Code ' = 1002 ret[' msg '] = ' request exception ' return Jsonresponse (ret) # Business Code class Order (Apiview): # Register Custom Authentication class, can have multiple, from left to right authentication match authentication_classes = [Authtication,] def G ET (self, request): # Request.user This value equals the first value of the tuple returned by authtication # Request.auth this value equals autht Ication returns the second value of the tuple, ret = {' Code ': $, ' msg ': None, ' Data ': none} ret[' data ' = ' Welcome to the system ' Return Jsonresponse (ret)
?
?
Rest_framework built-in authentication class:
BasicAuthentication # 基于浏览器实现的 Basic 认证, ftp 使用网页登录时使用的就是 Basic 认证SessionAuthentication # 基于 django 的 user.is_active 进行认证TokenAuthentication # 简单的基于 token 的认证RemoteUserAuthentication # 简单的远程用户认证实现
?
?
To configure the globally active authentication class and anonymous users:
自定义的认证类如果每次都在指定的类中使用 authentication_classes 指定那么就有可能出现大量的重复代码我们可以通过全局设置让指定的认证类对继承至 APIView 的所有类生效settings.py REST_FRAMEWORK = { # 设置全局生效的认证类(可以有多个) # app01 为 django app 的名称 # utils 为 app 目录下面的 utils 目录(这个目录必须包含 __init__.py 文件) # auth 为 utils 目录下面的 auth.py 文件 # Authtication 为 auth.py 文件里面的 Authtication 类 # 这儿的设置其实就是使用 from ... import ... 的路径 ‘DEFAULT_AUTHENTICATION_CLASSES‘: ["app01.utils.auth.Authtication",], #匿名用户配置 ‘UNAUTHENTICATED_USER‘: None, # 设置匿名用户的用户名, 默认为 AnonymousUser, 使用 request.user 查看 ‘UNAUTHENTICATED_TOKEN‘: None, # 设置匿名用户的 token, 默认为 None, 使用 request.auth 查看 }
?
?
Specifies that the View class does not use the Global authentication class:
在不使用全局认证类的 View 类中添加 authentication_classes = [] 或者 authentication_classes = [‘xxxx‘]# authentication_classes = [] 表示不使用认证# authentication_classes = [‘xxxx‘], xxxx 表示当前类需要使用的认证类用于替换全局类
Django Rest Framework user authentication