1.DRF认证组件之视图注册用法(自定义简单使用)
settings.py配置
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'rest_framework', ]
urls.py:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/', views.CourseView.as_view(),name='courses'), ]
veiws.py
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView from rest_framework import exceptions # Create your views here. #实例url:http://127.0.0.1:8000/book/?token=1 class MyAuth(object): def authenticate(self, request): # 该示例认证是需要在请求的url加上参数token(实际直接是校验用户名或密码或者登陆标识等) token = request._request.GET.get('token') if not token: raise exceptions.AuthenticationFailed('未认证用户!!!') return ('认证通过的request.user', 'request.auth') # 认证函数执行结果如果通过则为元组,元组第一个元素封装在为request.user,第二个参数封装在request.auth中 def authenticate_header(self, request): pass class CourseView(APIView): # 认证组件 authentication_classes = [MyAuth, ] def get(self, request): print(request.user)#request.user在APIViewD的dispatch中进行封装的 return HttpResponse('GET') def post(self, request): return HttpResponse('POST') def put(self, request): return HttpResponse('PUT') def patch(self, request): return HttpResponse('PATCH') def delete(self, request): return HttpResponse('DELETE')
2.DRF认证组件的使用(局部和全局)
方式一:局部配置---视图类中添加类变量 authentication_classes=[MyAuth,]---(认证类列表)
settings.py配置见上(注册rest_framework应用)
models.py
from django.db import models # Create your models here class UserInfo(models.Model): """ 用户表 """ user_type_choices = [ (1, '普通用户'), (2, 'VIP用户'), (3, 'SVIP用户'), ] user_type = models.IntegerField(choices=user_type_choices) username = models.CharField(max_length=10, unique=True) password = models.CharField(max_length=12, null=False) class UserToken(models.Model): """ token表 """ user = models.OneToOneField(to='UserInfo') token = models.CharField(max_length=64) create_time = models.DateTimeField(auto_now=True) class Book(models.Model): name = models.CharField(max_length=12)
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/v1/login', views.AuthView.as_view()), url(r'^book/', views.CourseView.as_view(),name='courses'), ]
views.py
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView from rest_framework import exceptions from app01 import models from django.http import JsonResponse # Create your views here. # 实例url:http://127.0.0.1:8000/book/?token=1 #认证类,每个类使用都需要加上类变量参数authentication_classes = [MyAuth, ] class MyAuth(object): def authenticate(self, request): # 该示例认证是需要在请求的url加上参数token(实际直接是校验用户名或密码或者登陆标识等) token = request._request.GET.get('token') token_obj = models.UserToken.objects.get(token=token) if not token_obj: raise exceptions.AuthenticationFailed('未认证用户!!!') return (token_obj.user, 'request.auth') # 认证函数执行结果如果通过则为元组,元组第一个元素封装在为request.user,第二个元素封装为request.auth def authenticate_header(self, request): pass class CourseView(APIView): # (1)认证组件 authentication_classes = [MyAuth, ] def get(self, request): print(request.user) # request.user在认证组件中进行封装的 return HttpResponse('GET') def post(self, request): return HttpResponse('POST') def put(self, request): return HttpResponse('PUT') def patch(self, request): return HttpResponse('PATCH') def delete(self, request): return HttpResponse('DELETE') import time import hashlib def token_md5(username): """ 自定义token :param username: :return: """ t = time.time() md5 = hashlib.md5(str(t).encode('utf-8')) md5.update(username.encode('utf-8')) return md5.hexdigest() class AuthView(APIView): def post(self, request): """ 用户登录 :param request:进行封装之后的request对象 :return: 登录结果信息 """ ret = {'code': 0, 'msg': ''} print(request._request.POST) username = request._request.POST.get('username', None) password = request._request.POST.get('password', None) # 每次登陆如果有就更新没有就创建 try: user_obj = models.UserInfo.objects.filter(username=username, password=password).first() if user_obj: token = token_md5(username) print(token) # 每次登陆如果有就更新没有就创建 models.UserToken.objects.update_or_create(user=user_obj, defaults={'token': token}) ret['msg'] = '登陆成功!' ret['token'] = token else: ret['code'] = 1 ret['msg'] = '账号或密码有误!!!' except Exception as e: ret['code'] = 2 ret['msg'] = '未知错误!!!' finally: return JsonResponse(ret)
方式二:全局配置----在settings.py配置文件中加载REST_FRAMEWORK配置
settings.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'rest_framework', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES' : ['app01.utils.auth.MyAuth',],#可以自定义多个认证类 'UNAUTHENTICATED_USER':lambda :'匿名用户request.user自定义值',#request.user有默认值,可以直接写None 'UNAUTHENTICATED_TOKEN':lambda :'request.auth自定义值',#request.auth有默认值,可以直接写None }
utils--auth.py--MyAuth认证类
from rest_framework import exceptions from app01 import models class MyAuth(object): def authenticate(self, request): # 该示例认证是需要在请求的url加上参数token(实际直接是校验用户名或密码或者登陆标识等) token = request._request.GET.get('token') token_obj = models.UserToken.objects.get(token=token) if not token_obj: raise exceptions.AuthenticationFailed('未认证用户!!!') return (token_obj.user, 'request.auth') # 认证函数执行结果如果通过则为元组,元组第一个元素封装在为request.user,第二个元素封装为request.auth def authenticate_header(self, request): pass
models.py
from django.db import models # Create your models here class UserInfo(models.Model): """ 用户表 """ user_type_choices = [ (1, '普通用户'), (2, 'VIP用户'), (3, 'SVIP用户'), ] user_type = models.IntegerField(choices=user_type_choices) username = models.CharField(max_length=10, unique=True) password = models.CharField(max_length=12, null=False) class UserToken(models.Model): """ token表 """ user = models.OneToOneField(to='UserInfo') token = models.CharField(max_length=64) create_time = models.DateTimeField(auto_now=True) class Book(models.Model): name = models.CharField(max_length=12)
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/v1/login', views.AuthView.as_view()), url(r'^book/', views.CourseView.as_view(),name='courses'), ]
views.py
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView from rest_framework import exceptions from app01 import models from django.http import JsonResponse # 实例url:http://127.0.0.1:8000/book/?token=1 class CourseView(APIView): # (1)认证组件 authentication_classes = [MyAuth, ] def get(self, request): print(request.user) #request.user在APIViewD的dispatch中进行封装的 return HttpResponse('GET') def post(self, request): return HttpResponse('POST') def put(self, request): return HttpResponse('PUT') def patch(self, request): return HttpResponse('PATCH') def delete(self, request): return HttpResponse('DELETE') import time import hashlib def token_md5(username): """ 自定义token :param username: :return: """ t = time.time() md5 = hashlib.md5(str(t).encode('utf-8')) md5.update(username.encode('utf-8')) return md5.hexdigest() class AuthView(APIView): #如果不注册自定义组件,走默认的认证,最后返回了request.user和request.auth都是匿名用户默认值,可以在settings.py中加载自定义配置 def post(self, request): """ 用户登录 :param request:进行封装之后的request对象 :return: 登录结果信息 """ ret = {'code': 0, 'msg': ''} print(request._request.POST) username = request._request.POST.get('username', None) password = request._request.POST.get('password', None) # 每次登陆如果有就更新没有就创建 try: user_obj = models.UserInfo.objects.filter(username=username, password=password).first() if user_obj: token = token_md5(username) print(token) # 每次登陆如果有就更新没有就创建 models.UserToken.objects.update_or_create(user=user_obj, defaults={'token': token}) ret['msg'] = '登陆成功!' ret['token'] = token else: ret['code'] = 1 ret['msg'] = '账号或密码有误!!!' except Exception as e: ret['code'] = 2 ret['msg'] = '未知错误!!!' finally: return JsonResponse(ret)
3.DRF认证组件的继承类(常用)
utils--auth.py--MyAuth认证类
from rest_framework import exceptions from app01 import models from rest_framework.authentication import BaseAuthentication,BasicAuthentication # 实例url:http://127.0.0.1:8000/book/?token=1 #认证类(可以定义多个): # 方式一:每个类使用都需要加上类变量参数authentication_classes = [MyAuth, ] #方式二:在setings.py配置中加载REST_FRAMEWORK配置----'DEFAULT_AUTHENTICATION_CLASSES' : [], # class MyAuth(object): class MyAuth(BaseAuthentication):#可以直接继承BaseAuthentication类,可以省略authenticate_header方法,或者继承BasicAuthentication def authenticate(self, request): # 该示例认证是需要在请求的url加上参数token(实际直接是校验用户名或密码或者登陆标识等) token = request._request.GET.get('token') token_obj = models.UserToken.objects.get(token=token) if not token_obj: raise exceptions.AuthenticationFailed('未认证用户!!!') return (token_obj.user', 'request.auth') # 认证函数执行结果如果通过则为元组,元组第一个元素封装在为request.user # def authenticate_header(self, request): # pass
settings.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'rest_framework', ] REST_FRAMEWORK = { #认证组件 'DEFAULT_AUTHENTICATION_CLASSES' : ['app01.utils.auth.MyAuth',],#可以自定义多个认证类 'UNAUTHENTICATED_USER':lambda :'匿名用户request.user自定义值',#request.user有默认值,可以直接写None 'UNAUTHENTICATED_TOKEN':lambda :'request.auth自定义值',#request.auth有默认值,可以直接写None }