码迷,mamicode.com
首页 > 其他好文 > 详细

Django Rest framework

时间:2019-01-28 19:12:33      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:rtc   class   shortcut   14.   char   short   inview   views   hid   

首先我们需要先了解一下CBV的执行流程:

通常在写CBV模式时,会在路由匹配时re_path(‘login/‘, views.LoginView.as_view()),进入as_view() 中发现最后返回的是view,然后又发现view函数中最后返回的是dispatch(),进入该函数发现,其实其中就是通过反射执行request.method对应的方法。总结,CBV本质是通过执行反射进行的。而且在执行对应方法之前会执行dispatch().

框架之认证系统

当我们的视图对应的类继承的是rest_framework.views 的APIView时,我们进入dispatch(),发现request = self.initialize_request(request, *args, **kwargs)中最后返回的是Request的对象,对原生request进行封装(进入Request发现原生的request为_request),并且添加了如authenticators=self.get_authenticators()等属性,进入get_authenticators()返回的是authentication_classes的实例对象,进而发现默认authentication_classes是对读配置文件的。

ok,我们继续看dispatch(),在封装之后又self.initial(request, *args, **kwargs),initial中又走self.perform_authentication(request),该方法返回了request.user,这时的request是最开始封装的request,查看Requet其中的user,发现走了self._authenticate(),其中对self.authenticators进行循环,执行对应的authenticate()。

技术分享图片
from django.db import models

# Create your models here.
class UserInfo(models.Model):
    username = models.CharField(max_length=16)
    password = models.CharField(max_length=32)
    type = models.SmallIntegerField(
        choices=((1, 普通用户), (2, VIP用户)),
        default=1
    )


class Token(models.Model):
    user = models.OneToOneField(to=UserInfo,on_delete=models.CASCADE)
    token_code = models.CharField(max_length=128)
models.py
技术分享图片
from django.shortcuts import render,HttpResponse
from app01 import models
from django.views import View
from rest_framework.views import APIView
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from django.http import JsonResponse
# Create your views here.

def get_random_token(username):
    """
    根据用户名和时间戳生成随机token
    :param username:
    :return:
    """
    import hashlib, time
    timestamp = str(time.time())
    m = hashlib.md5(bytes(username, encoding="utf8"))
    # 加盐
    m.update(bytes(timestamp, encoding="utf8"))
    return m.hexdigest()
# 自定义认证类
class MyAuth(BaseAuthentication):
    def authenticate(self,request):
        try:
            token = request._request.GET.get(token)
            token_obj = models.Token.objects.get(token_code=token)
            if token_obj:
                return (token_obj.user, token_obj)
            else:
                raise AuthenticationFailed(认证失败)
        except Exception as e:
            raise AuthenticationFailed(请携带token,认证失败)
class LoginView(APIView):
    """
    校验用户名密码是否正确从而生成token的视图
    """
    authentication_classes = [MyAuth, ]
    def post(self, request):
        # self.dispatch()
        res = {"code": 0}
        username = request.data.get("username")
        password = request.data.get("password")
        user = models.UserInfo.objects.filter(username=username, password=password).first()
        if user:
            # 如果用户名密码正确
            token = get_random_token(username)
                                                # 找到user对象,有就更新(更新token_code),没有就创建
            models.Token.objects.update_or_create(defaults={"token_code": token}, user=user)
            res["token"] = token
        else:
            res["code"] = 1
            res["error"] = "用户名或密码错误"
        return JsonResponse(res)

    def get(self,request):
        return HttpResponse(get)
views.py

 

如果我们自己写了authentication_classes,那么就会走我们写在其中的类的实例对象,我自定义认证类中必须写有authenticate()实现认证逻辑。

re_path(‘login/‘, views.LoginView.as_view())

Django Rest framework

标签:rtc   class   shortcut   14.   char   short   inview   views   hid   

原文地址:https://www.cnblogs.com/zhaowei5/p/10331242.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!