RestFramework:四、認(rèn)證組件

一、創(chuàng)建LoginAuth類完成認(rèn)證過(guò)程

創(chuàng)新互聯(lián)主營(yíng)鎮(zhèn)平網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,重慶APP開發(fā)公司,鎮(zhèn)平h5微信小程序開發(fā)搭建,鎮(zhèn)平網(wǎng)站營(yíng)銷推廣歡迎鎮(zhèn)平等地區(qū)企業(yè)咨詢

使django支持 framework

在settings.py中的INSTALLED_APPS字段添加:

"rest_framework"


urls.py

url(r'^login/', views.Login.as_view()),
url(r'^books/', views.Books.as_view()),

models.py

from django.db import models

# Create your models here.
class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    # 寫choice
    user_choice=((0,'普通用戶'),(1,'會(huì)員'),(2,'超級(jí)用戶'))
    # 指定choice,可以快速的通過(guò)數(shù)字,取出文字
    user_type=models.IntegerField(choices=user_choice,default=0)
    pwd = models.CharField(max_length=32)

class UserToken(models.Model):
    token = models.CharField(max_length=64)
    user = models.OneToOneField(to=UserInfo)

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()

    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

    def __str__(self):
        return self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

    def test(self):
        return self.email

遷移數(shù)據(jù)庫(kù)

python3 manage makemigrations
python3 manage migrate


app01/MySerializer.py

from rest_framework import serializers
from app01 import models
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields='__all__'

views.py

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.views import APIView
from app01 import models
import hashlib
import time
from django.core.exceptions import ObjectDoesNotExist
from app01 import MySerializer


# Create your views here.

def get_token(name):
    # 生成一個(gè)md5對(duì)象
    md5 = hashlib.md5()
    # 往里添加值,必須是bytes格式
    # time.time()生成時(shí)間戳類型,轉(zhuǎn)成字符串,再encode轉(zhuǎn)成bytes格式
    md5.update(str(time.time()).encode('utf-8'))
    md5.update(name.encode('utf-8'))
    return md5.hexdigest()


class Login(APIView):
    authentication_classes = []

    def post(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '登錄成功'}
        name = request.data.get('name')
        pwd = request.data.get('pwd')
        try:
            user = models.UserInfo.objects.get(name=name, pwd=pwd)
            # 校驗(yàn)通過(guò),登錄成功,生成一個(gè)隨機(jī)字符串(身份標(biāo)識(shí))token
            token = get_token(name)
            # 保存到數(shù)據(jù)庫(kù)
            # update_or_create更新或者創(chuàng)建
            models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
            response['token'] = token
        except ObjectDoesNotExist as e:
            response['status'] = 101
            response['msg'] = '用戶名或密碼錯(cuò)誤'
        except Exception as e:
            response['status'] = 102
            # response['msg']='未知錯(cuò)誤'
            response['msg'] = str(e)
        return JsonResponse(response, safe=False)


from rest_framework import exceptions


class LoginAuth():
    # 函數(shù)名必須叫這個(gè)名字,接收必須兩個(gè)參數(shù),第二個(gè)參數(shù)是request對(duì)像
    def authenticate(self, request):
        # 從request對(duì)像中取出token (也可以從其他地方中?。?        token = request.query_params.get('token')
        # 去數(shù)據(jù)庫(kù)中查詢
        ret = models.UserToken.objects.filter(token=token)
        if ret:
            # 可以查到,說(shuō)明認(rèn)證通過(guò),返回空
            return None
        #   否則會(huì)報(bào)異常
        raise exceptions.APIException('認(rèn)證失敗')


from rest_framework.request import Request


# class Books(APIView):
#     # 列表中類型不能加括號(hào)
#     authentication_classes = [LoginAuth, ]
#
#     def get(self, request, *args, **kwargs):
#         response = {'status': 100, 'msg': '查詢成功'}
#         # 必須登錄以后,才能獲取數(shù)據(jù)
#         # 取出token,取數(shù)據(jù)庫(kù)驗(yàn)證,是否登錄
#         token = request.query_params.get('token')
#         ret = models.UserToken.objects.filter(token=token)
#         if ret:
#             # 認(rèn)證通過(guò),是登錄用戶
#             ret = models.Book.objects.all()
#             book_ser = MySerializer.BookSerializer(ret, many=True)
#             response['data'] = book_ser.data
#         else:
#             response['status'] = 101
#             response['msg'] = '認(rèn)證不通過(guò)'
#         return JsonResponse(response, safe=False)

# 與上面的Books類功能一樣,但比上面的那個(gè)更加簡(jiǎn)潔。
class Books(APIView):
    # 列表中類型不能加括號(hào)
    authentication_classes = [LoginAuth, ]

    def get(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '查詢成功'}
        ret = models.Book.objects.all()
        book_ser = MySerializer.BookSerializer(ret, many=True)
        response['data'] = book_ser.data
        return JsonResponse(response, safe=False)

數(shù)據(jù)庫(kù)中添加數(shù)據(jù)測(cè)試:

Rest Framework:四、認(rèn)證組件

Rest Framework:四、認(rèn)證組件

Rest Framework:四、認(rèn)證組件

使用Postman測(cè)試:

功能:登錄后方可查看書的詳情信息

使用數(shù)據(jù)庫(kù)中的用戶名與密碼登錄服務(wù):

Rest Framework:四、認(rèn)證組件

使用token登錄來(lái)驗(yàn)證查詢書的詳情信息

Rest Framework:四、認(rèn)證組件

若是token驗(yàn)證不成功,就會(huì)返回:

Rest Framework:四、認(rèn)證組件

二、認(rèn)證組件的全局使用與局部使用

urls.py、models.py、不變

局部使用:

views.py

from app01.MyAuth import LoginAuth
class Books(APIView):
    # 列表中類型不能加括號(hào)
    # 認(rèn)證組件局部使用
    authentication_classes = [LoginAuth, ]
    # 認(rèn)證組件,局部禁用 authentication_classes = []
    def get(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '查詢成功'}
        ret = models.Book.objects.all()
        book_ser = MySerializer.BookSerializer(ret, many=True)
        response['data'] = book_ser.data
        return JsonResponse(response, safe=False)

app01/MyAuth.py

from rest_framework import exceptions
from app01 import models
# 用dnf 認(rèn)證,寫一個(gè)類
class LoginAuth():
    # 函數(shù)名必須叫這個(gè)名字,接收必須兩個(gè)參數(shù),第二個(gè)參數(shù)是request對(duì)像
    def authenticate(self, request):
        # 從request對(duì)像中取出token (也可以從其他地方中取)
        token = request.query_params.get('token')
        # 去數(shù)據(jù)庫(kù)中查詢
        ret = models.UserToken.objects.filter(token=token)
        if ret:
            # 可以查到,說(shuō)明認(rèn)證通過(guò),返回空
            return None
        #   否則會(huì)報(bào)異常
        raise exceptions.APIException('認(rèn)證失敗')

-全局使用
    -在setting中配置:

    使django支持 framework

    在settings.py中的INSTALLED_APPS字段添加:

    "rest_framework"

REST_FRAMEWORK={
    'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',],
}

-局部禁用,views.py中有:

認(rèn)證組件,局部禁用 authentication_classes = []


三、權(quán)限組建

用戶身份不同,權(quán)限也不同

urls.py

url(r'^login/', views.Login.as_view()),
url(r'^books/', views.Books.as_view()),
url(r'^authors/', views.Authors.as_view()),
url(r'^users/', views.User.as_view()),

views.py

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.views import APIView
from app01 import models
import hashlib
import time
from django.core.exceptions import ObjectDoesNotExist
from app01 import MySerializer


# Create your views here.

def get_token(name):
    # 生成一個(gè)md5對(duì)象
    md5 = hashlib.md5()
    # 往里添加值,必須是bytes格式
    # time.time()生成時(shí)間戳類型,轉(zhuǎn)成字符串,再encode轉(zhuǎn)成bytes格式
    md5.update(str(time.time()).encode('utf-8'))
    md5.update(name.encode('utf-8'))
    return md5.hexdigest()


class Login(APIView):
    authentication_classes = []
    permission_classes = []

    def post(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '登錄成功'}
        name = request.data.get('name')
        pwd = request.data.get('pwd')
        try:
            user = models.UserInfo.objects.get(name=name, pwd=pwd)
            # 校驗(yàn)通過(guò),登錄成功,生成一個(gè)隨機(jī)字符串(身份標(biāo)識(shí))token
            token = get_token(name)
            # 保存到數(shù)據(jù)庫(kù)
            # update_or_create更新或者創(chuàng)建
            models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
            response['token'] = token
        except ObjectDoesNotExist as e:
            response['status'] = 101
            response['msg'] = '用戶名或密碼錯(cuò)誤'
        except Exception as e:
            response['status'] = 102
            # response['msg']='未知錯(cuò)誤'
            response['msg'] = str(e)
        return JsonResponse(response, safe=False)

from rest_framework import exceptions
from app01.MyAuth import LoginAuth
from rest_framework.request import Request

class Books(APIView):
    # 列表中類型不能加括號(hào)
    # 認(rèn)證組件局部使用
    # authentication_classes = [LoginAuth, ]
    # 認(rèn)證組件,局部禁用 authentication_classes = []
    def get(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '查詢成功'}
        ret = models.Book.objects.all()
        book_ser = MySerializer.BookSerializer(ret, many=True)
        response['data'] = book_ser.data
        return JsonResponse(response, safe=False)

# 只能超級(jí)用戶可以查看作者詳情,其他人不能看
from app01.MyAuth import UserPermission

class Authors(APIView):
    # 局部使用
    # permission_classes = [UserPermission,]
    # 局部禁用
    # permission_classes = []

    def get(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '查詢成功'}
        ret = models.Author.objects.all()

        ser = MySerializer.AuthorSerializer(ret, many=True)
        response['data'] = ser.data
        return JsonResponse(response, safe=False)
class User(APIView):
    def get(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '查詢成功'}
        ret = models.UserInfo.objects.all()
        ser = MySerializer.UserSer(ret, many=True)
        response['data'] = ser.data
        return JsonResponse(response, safe=False)

settings.py中添加:

# 認(rèn)證組件全局使用
REST_FRAMEWORK={
    'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',],
    'DEFAULT_PERMISSION_CLASSES':['app01.MyAuth.UserPermission',],
}

app01/MyAuth.py

from rest_framework import exceptions
from app01 import models
from rest_framework.authentication import BaseAuthentication

# 用dnf 認(rèn)證,寫一個(gè)類
class LoginAuth(BaseAuthentication):
    # 函數(shù)名必須叫這個(gè)名字,接收必須兩個(gè)參數(shù),第二個(gè)參數(shù)是request對(duì)像
    def authenticate(self, request):
        # 從request對(duì)像中取出token (也可以從其他地方中?。?        token = request.query_params.get('token')
        print(token)
        # 去數(shù)據(jù)庫(kù)中查詢
        ret = models.UserToken.objects.filter(token=token).first()
        print(ret)
        if ret:
            # 可以查到,說(shuō)明認(rèn)證通過(guò),返回空
            return ret.user, ret
        #   否則會(huì)報(bào)異常
        raise exceptions.APIException('認(rèn)證失敗')

from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
    # message是出錯(cuò)顯示的中文
    message = '沒(méi)權(quán)限查看'

    def has_permission(self, request,view):
        print(request.user)
        user_type = request.user.user_type

        print(user_type)
        # 取出用戶類型對(duì)應(yīng)的文字
        # 固定用法:get_字段名字_display()
        user_type_name = request.user.get_user_type_display()
        print(user_type_name)
        if user_type == 2:
            return True
        else:
            return False

app01/MySerializer.py

from rest_framework import serializers
from app01 import models

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        fields = '__all__'
class UserSer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields='__all__'
    # 顯示用戶類型以中文顯示
    user_type=serializers.CharField(source='get_user_type_display')
    # 上面一句話就ok
    # user_type=serializers.SerializerMethodField()
    # def get_user_type(self,obj):
    #     return obj.get_user_type_display()

models.py

from django.db import models


# Create your models here.
# 用戶信息
class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    # 寫choice
    user_choice = ((0, '普通用戶'), (1, '會(huì)員'), (2, '超級(jí)用戶'))
    # 指定choice,可以快速的通過(guò)數(shù)字,取出文字
    user_type = models.IntegerField(choices=user_choice, default=0)
    pwd = models.CharField(max_length=32)

# 用戶token
class UserToken(models.Model):
    token = models.CharField(max_length=64)
    user = models.OneToOneField(to=UserInfo)


class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()

    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

    def __str__(self):
        return self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

    def test(self):
        return self.email

數(shù)據(jù)庫(kù)中添加數(shù)據(jù):

Rest Framework:四、認(rèn)證組件

Rest Framework:四、認(rèn)證組件

使用Postman來(lái)登錄用戶獲取token:

Rest Framework:四、認(rèn)證組件

Rest Framework:四、認(rèn)證組件

使用Postman 中的"s_jun"(只有超級(jí)用戶有權(quán)限查看,其他人沒(méi)有權(quán)限查看)用戶的token測(cè)試:

Rest Framework:四、認(rèn)證組件

其他用戶的token查看:

Rest Framework:四、認(rèn)證組件


使用postman 查看用戶身份類型以及中文方式顯示

Rest Framework:四、認(rèn)證組件



分享文章:RestFramework:四、認(rèn)證組件
網(wǎng)站地址:http://muchs.cn/article44/pjjhee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、外貿(mào)網(wǎng)站建設(shè)虛擬主機(jī)、、軟件開發(fā)網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)