rest-framework的认证组件

认证组件

1.登录认证(与组件无关):

首先要在model表内添加用户表和token表:

from django.db import models

# Create your models here.
class User(models.Model):
    name=models.CharField(max_length=32)
    pwd=models.CharField(max_length=32)

class Token(models.Model):
    user=models.OneToOneField("User",on_delete=models.CASCADE)
    token=models.CharField(max_length=128)
import hashlib,time
def get_random_str(user):
    ctime=str(time.time())
    md5=hashlib.md5(bytes(user,encoding="utf-8"))
    md5.update(bytes(ctime,encoding="utf-8"))

    return md5.hexdigest()


class LoginView(APIView):
    def post(self,request):
        name=request.data.get("name")
        pwd=request.data.get("pwd")
        user=User.objects.filter(name=name,pwd=pwd).first()
        res={"state_code":1000,"msg":None}
        if user:
            random_str=get_random_str(user.name)
            toekn=Token.objects.update_or_create(user=user,defaults={"token":random_str})
            res["token"]=random_str
        else:
            res["state_code"]=1001   #错误的状态码
            res["msg"]="用户名密码错误!"

        return Response(json.dumps(res))

2.局部认证:

# Author:Jesi
# Time : 2018/10/6 18:14
from .models import *
from rest_framework.authentication import BaseAuthentication

from rest_framework import exceptions
class  TokenAuth(BaseAuthentication):
    def authenticate(self,request):
        '''函数名必须叫authenticate'''
        # 验证条件根据需求设置(此示例为需要有token值)
        token=request.GET.get("token")
        token_obj=Token.objects.filter(token=token).first()
        if not token_obj:
            # 如果验证失败,需要跑出AuthenticationFailed错误
           raise exceptions.AuthenticationFailed("验证失败!")
        else:
            # 如果验证成功,需要返回一个元组,分别是用户以及验证类的实例对象,然后内部会赋值给request.user和request.auth
            return token_obj.user.name,token_obj.token

    def authenticate_header(self,request):
        #加上上面的基础类继承,那么这个header方法就可以不用写了。
        pass

在视图中只需要加一句就OK了。

class BookView(APIView):
    authentication_classes = [TokenAuth]  # 注意,值为一个列表,可以放多个认证组件类名 
    def get(self,request):
        print(request.user)   #token_obj.user.name
        print(request.auth)   #token_obj.token
        book_list=Book.objects.all()
        # bs=BookSerializers(book_list,many=True)
        bs2=BookModelSerializers(book_list,many=True,context={'request': request})
        # return Response(bs.data)
        return Response(bs2.data)

这里打印的2个request.user,request.auth分别就是上面认证类返回的token_obj.user.name和token_obj.token。是一个元组。

3.全局配置:

将认证类放到一个util.py的一个额外文件下:

# Author:Jesi
# Time : 2018/10/6 18:14
from .models import *
from rest_framework.authentication import BaseAuthentication

from rest_framework import exceptions
class  TokenAuth(BaseAuthentication):
    def authenticate(self,request):
        token=request.GET.get("token")
        token_obj=Token.objects.filter(token=token).first()
        if not token_obj:
           raise exceptions.AuthenticationFailed("验证失败!")
        else:
            return token_obj.user.name,token_obj.token

    def authenticate_header(self,request):
        #加上上面的基础类继承,那么这个header就可以不用写了。
        pass

然后在settings里面进行一个配置:

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.utils.TokenAuth"]
}

这样全局就都拥有了认证的组件。如果要查看书籍,作者等操作的时候需要带上token通过认证类的验证才可以。

http://127.0.0.1:8000/books/?token=7f9038f36213a9e6aa6c3ad51043d9d0

最后:

这样配置之后,每个视图类都要经过认证成功之后才能执行下一步,如果有某些方法不需要认证,如login函数,则需要在login函数中单独加入一个配置属性:

authentication_classes = [] #自己的类里有的话就调用此类的配置,为空既什么都不做

猜你喜欢

转载自www.cnblogs.com/geogre123/p/9748051.html