1、认证简介
只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件;
2、登录接口和token的使用
settings.py
INSTALLED_APPS = [ ..... 'rest_framework', ]
models.py
from django.db import models # Create your models here. class User(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=64) # 和User表做一对一关联 class Token(models.Model): # OneToOneField源码本质就是Foreignkey+unique约束 user = models.OneToOneField(to='User') token = models.CharField(max_length=64)
执行数据库迁移命令;
在数据库里插入数据:
views.py
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BaseAuthentication from app01 import models from django.core.exceptions import ObjectDoesNotExist import uuid # Create your views here. class Login(APIView): def post(self, request): response={'code':100, 'msg':'登录成功'} name = request.data.get('name') pwd = request.data.get('pwd') try: # get有且只有一条才不报错,其他情况都抛异常 user = models.User.objects.filter(name=name, pwd=pwd).get() # 登录成功,需要去token表中存数据 # 生成一个唯一的id token = uuid.uuid4() # update_or_create为了添加数据时防止重复. 先去查询, 如果没有再创建, 如果有则更新 models.Token.objects.update_or_create(user=user, defaults={'token':token}) response['token'] = token except ObjectDoesNotExist as e: response['code']=101 response['msg']='用户名或密码错误' except Exception as e: response['code'] = 102 response['msg'] = str(e) return Response(response)
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'^login/', views.Login.as_view()), ]
在postman中验证:
3、认证组件
REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案。
接下来我们就自己实现一个基于用户名密码的认证方案:
--认证类的局部使用
models.py和上面相同;
在app下写一个MyAuths.py
from app01 import models from rest_framework.exceptions import AuthenticationFailed from rest_framework.authentication import BaseAuthentication # 认证类 class MyAuth(BaseAuthentication): def authenticate(self, request): token = request.GET.get('token') token_obj = models.Token.objects.filter(token=token).first() if token_obj: # 有值表示登陆了 # token_obj.user当前登录的user对象 return token_obj.user,token_obj else: # 没有值表示没登陆,抛异常 raise AuthenticationFailed('您没有登录')
views.py中添加一个Book类,只有验证登录后才走Book:
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from app01 import models from django.core.exceptions import ObjectDoesNotExist import uuid # 导入MyAuth from app01.MyAuths import MyAuth # Create your views here. class Books(APIView): # 使用自定义的认证类MyAuth,可以写多个认证类 authentication_classes = [MyAuth,] def get(self, request): # request.user就是当前登录用户,可以拿到用户名,然后再做各种操作 print(request.user.name) return Response('返回了所有图书') class Login(APIView): def post(self, request): response={'code':100, 'msg':'登录成功'} name = request.data.get('name') pwd = request.data.get('pwd') try: # get有且只有一条才不报错,其他情况都抛异常 user = models.User.objects.filter(name=name, pwd=pwd).get() # 登录成功,需要去token表中存数据 # 生成一个唯一的id token = uuid.uuid4() # update_or_create为了添加数据时防止重复. 先去查询, 如果没有再创建, 如果有则更新 models.Token.objects.update_or_create(user=user, defaults={'token':token}) response['token'] = token except ObjectDoesNotExist as e: response['code']=101 response['msg']='用户名或密码错误' except Exception as e: response['code'] = 102 response['msg'] = str(e) return Response(response)
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'^books/', views.Books.as_view()), url(r'^login/', views.Login.as_view()), ]
在postman中验证,在url后加上了正确的token,就可以走Book了
--认证类的全局使用
在settings.py中设置,设置后视图中就不用一个个的引用了:
# 列表里写上类名路径,可以写多个 REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["app01.MyAuths.MyAuth",] }
--认证类的局部禁用
在全局使用时,如果某些类不想使用(比如login就不能用),怎么办呢?
这时就要使用局部禁用了:
# 直接在要局部禁用的视图类中,写以下内容即可 authentication_classes = []