rest-framework之认证组件

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)

执行数据库迁移命令;

在数据库里插入数据:

image


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中验证:

image


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了

image


--认证类的全局使用

在settings.py中设置,设置后视图中就不用一个个的引用了:

# 列表里写上类名路径,可以写多个
REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.MyAuths.MyAuth",]
}


--认证类的局部禁用

在全局使用时,如果某些类不想使用(比如login就不能用),怎么办呢?

这时就要使用局部禁用了:

# 直接在要局部禁用的视图类中,写以下内容即可
authentication_classes = []
posted @ 2020-03-18 09:36  米兰的小铁將  阅读(144)  评论(0)    收藏  举报