Rest-framework之drf认证组件,权限组件+不存数据库的token认证
生活随笔
收集整理的這篇文章主要介紹了
Rest-framework之drf认证组件,权限组件+不存数据库的token认证
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? Rest-framework之drf認證組件,權限組件
django中一個請求時一個reques,如果在哪個位置改了request,那么到了后面就是修改過的request 昨日回顧:認證:
-寫一個認證類,(可以繼承BaseAuthentication)
-注意:這個類要放在單獨的py文件中,(如果放在view中,全局配置無法使用)
-類中寫個函數:def authenticate(self,request)
-認證的判斷:
-取出token做驗證
-驗證通過,可以返回兩個值,一個給了request.user,一個給了request.auth
-驗證不通過,拋異常
-因為認證類可以寫多個,如果想讓多個都執行,放在前面的不能return值
-局部使用:
-在視圖類中
authentication_classes = [LoginAuth, ]
-全局使用:
-在setting中配置
-REST_FRAMEWORK={
'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',],
}
-局部禁用:
-在視圖類中
authentication_classes = [ ]
權限:
-寫一個權限類,(可以繼承BasePermission)
-注意:這個類要放在單獨的py文件中,(如果放在view中,全局配置無法使用)
-類中的方法:def has_permission(self,request,view)
-認證通過:返回True
-認證不通過:返回False
-返回值:布爾類型
-局部使用:
-在視圖類中:
-permission_classes = [UserPermission,]
-全局使用:
-在setting中配置
-REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES':['app01.MyAuth.UserPermission',]
}
-局部禁用:
-在視圖類中:
-permission_classes = []
choice的用法:
-拿出數字對應的中文:get_字段名_dispaly() 因為認證類可以寫多個,如果想要多個都執行,放在前面的就不能return值,可以return None
?
1.views視圖層
from django.shortcuts import render from rest_framework.views import APIView from app01 import models from django.core.exceptions import ObjectDoesNotExist import hashlib import time from django.http import JsonResponse from app01 import MySerializer from rest_framework.request import Request from rest_framework import exceptionsdef get_token(name):md5 = hashlib.md5() # 生成一個MD5對象# 往里添加值,必須是bytes格式# time.time()生成時間戳類型,轉成字符串,再encode轉成bytes格式md5.update(str(time.time()).encode('utf-8'))md5.update(name.encode('utf-8'))return md5.hexdigest()# 登錄接口 class Login(APIView):authentication_classes = []# 登錄就是使用post,get是返回一個頁面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)# 校驗通過,登陸成功,就生成一個隨機字符串(身份標識),tokentoken = get_token(name)# 保存到數據庫# user=user就是需要查詢的數據,defaults里面:token就是需要修改或者新增的數據models.UserToken.objects.update_or_create(user=user, defaults={'token': token})# 登陸成功之后把登錄返回給他,以后就帶著token過來response['token'] = tokenexcept ObjectDoesNotExist as e:response['status'] = 101response['msg'] = '用戶名或密碼錯誤'except Exception as e:# 萬能異常,里面只要出錯,程序就會走到這里response['status'] = 102# response['msg'] = '未知錯誤'# 把整個錯誤信息轉換成str類型,賦值給e,一般在測試時使用這個response['msg'] = str(e)# 如果不寫safe=False,只能序列化字典形式,如果字典里面又套了列表,或者直接是一個列表,就必須寫safe=Falsereturn JsonResponse(response, safe=False)from app01.MyAuth import LoginAuthclass Books(APIView):# 列表中類名不能加括號authentication_classes = [LoginAuth, ]def get(self, request, *args, **kwargs):# 只要通過認證,就能取到當前登錄用戶對象的密碼,id等信息# print(request.query_params)# print(request.user.name)# print(request.user.pwd)response = {'status': 100, 'msg': '查詢成功'}res = models.Book.objects.all()book_ser = MySerializer.BookSerializer(res, many=True)# 這個數據是需要返回給前臺的response['data'] = book_ser.data# print(book_ser.data)return JsonResponse(response, safe=False)# 需求:只能黃金會員才能查看作者詳情,其他會員不能看 from app01.MyAuth import UserPermissionclass Authors(APIView):# permission_classes = [UserPermission,]# 局部禁用permission_classes = []def get(self, request, *args, **kwargs):response = {'status': 100, 'msg': '查詢成功'}author_all = models.Author.objects.all()author_ser = MySerializer.AuthorSerializer(author_all, many=True)response['data'] = author_ser.datareturn JsonResponse(response, safe=False)class User(APIView):def get(self, request, *args, **kwargs):response = {'status': 100, 'msg': '查詢成功'}user_all = models.UserInfo.objects.all()user_ser = MySerializer.UserSerializer(user_all, many=True)response['data'] = user_ser.datareturn JsonResponse(response, safe=False) View Code2.MyAuth.py-認證組件和權限組件
from app01 import models from rest_framework import exceptions from rest_framework.authentication import BaseAuthentication# 認證組件,使用drf的認證,我們需要寫一個類 class LoginAuth(BaseAuthentication):# 函數名一定要叫authenticate,需要接收2個參數,第二個參數是request對象def authenticate(self, request):# 從request對象中取出token(也可以從其他地方取)token = request.query_params.get('token')# 去數據庫過濾,查詢ret = models.UserToken.objects.filter(token=token).first()if ret:# 能查到,說明認證通過,反回空# ret.user就是當前登錄用戶對象return ret.user, ret# 如果查不到,就拋出異常raise exceptions.APIException('認證失敗')#權限組件,誰有資格查看作者詳情信息 class UserPermission():# message是錯誤顯示的中文message = '您沒有權限查看'def has_permission(self, request, view):user_type = request.user.user_type# print(user_type)# 取出用戶類型對應的文字# 固定用法:get_字段名_display()user_type_name = request.user.get_user_type_display()print(user_type_name)if user_type == 2:return Trueelse:return False View Code3.MySerializer.py-序列化組件
from rest_framework import serializers from app01 import modelsclass BookSerializer(serializers.ModelSerializer):class Meta:model = models.Bookfields = '__all__'class AuthorSerializer(serializers.ModelSerializer):class Meta:model = models.Authorfields = '__all__'class UserSerializer(serializers.ModelSerializer):class Meta:model = models.UserInfofields = '__all__'user_type=serializers.CharField(source='get_user_type_display')# user_type = serializers.SerializerMethodField()# def get_user_type(self, obj):# return obj.get_user_type_display() View Code4.models層
from django.db import models# Create your models here. # 用戶信息 class UserInfo(models.Model):name = models.CharField(max_length=32)pwd = models.CharField(max_length=32)# 寫choiceuser_choice = ((0, '普通會員'), (1, '鉑金會員'), (2, '黃金會員'))# 指定choice,可以快速的通過數字,取出文字user_type = models.IntegerField(choices=user_choice,default=0)# 用戶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.nameclass Author(models.Model):nid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)age = models.IntegerField()author_detail = models.OneToOneField(to='AuthorDetail', to_field='nid', unique=True, on_delete=models.CASCADE)class AuthorDetail(models.Model):nid = models.AutoField(primary_key=True)telephone = models.BigIntegerField()birthday = models.DateField()addr = models.CharField(max_length=64)def __str__(self):return self.telephoneclass 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.namedef test(self):return self.email View Code5.settings.py
全局使用認證和權限 REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['app01.MyAuth.LoginAuth', ],'DEFAULT_PERMISSION_CLASSES': ['app01.MyAuth.UserPermission', ] }?6.urls.py路由層
urlpatterns = [url(r'^admin/', admin.site.urls),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()), ] View Code?7.不存數據庫的token認證
粗糙的丸子博客園 首頁 新隨筆 聯系 訂閱 管理 隨筆 - 18 文章 - 2 評論 - 0 哇哇哇哇 1.不存數據庫的token認證import hashlib from day98 import settingsdef check_token(token):ret = Trueuser_info = Nonetry:ll = token.split('|')# da89744b701b5d8bc5b9a76b4ddb3dd4 , {\"name\": \"cao\", \"id\": 1},已經切分成了一個列表md5 = hashlib.md5()# 需要給這個{\"name\": \"cao\", \"id\": 1}加密,它就是列表里的第一個值md5.update(ll[1].encode('utf-8'))# 在setting里面全局配置一下,給token加鹽md5.update(settings.password.encode('utf-8'))# hex=da89744b701b5d8bc5b9a76b4ddb3dd4hex = md5.hexdigest()if not hex == ll[0]:ret = Falseelse:user_info = ll[1]except Exception as e:ret = Falsereturn ret, user_infoclass LoginAuth(BaseAuthentication):# 函數名一定要叫authenticate,需要接收2個參數,第二個參數是request對象def authenticate(self, request):# 從request對象中取出token(也可以從其他地方取)token = request.query_params.get('token')# ret是布爾類型,表示驗證通過或者失敗,user_info是user的字典ret, user_info = check_token(token)if ret:# 能查到,說明認證通過,反回空# ret.user就是當前登錄用戶對象return user_info, None# 如果查不到,就拋出異常raise exceptions.APIException('認證失敗')View.py-登錄接口好文要頂 關注我 收藏該文 粗糙的丸子 關注 - 6 粉絲 - 0 0 0 ? 上一篇:Rest-framework之drf認證組件,權限組件 posted @ 2018-12-14 16:45 粗糙的丸子 閱讀(0) 評論(0) 編輯 收藏刷新評論刷新頁面返回頂部 發表評論 昵稱: 評論內容:退出 [Ctrl+Enter快捷鍵提交] 【推薦】超50萬VC++源碼: 大型組態工控、電力仿真CAD與GIS源碼庫! 【活動】華為云12.12會員節全場1折起 滿額送Mate20 【活動】華為云會員節云服務特惠1折起 【活動】騰訊云+社區開發者大會12月15日首都北京盛大起航!相關博文: · 哇哇cool~~~ · 嗚哇哇,嗚嘛嘛 · 哇哇哇~~ · Linux常用命令大全 · java網絡編程Socket通信詳解最新新聞: · 消失的90后CEO與賭場資本主義年代 · 從孟晚舟職場二三事說起 · 微軟可穿戴設備專利曝光:有望改善帕金森患者手部的顫抖影響 · 知乎架構調整:提高組織力 任命前蜜芽合伙人為CFO · Apple Music有個功能被蘋果砍掉了,但你可能從未用過它 ? 更多新聞...公告github com/粗糙的丸子 郵箱: 2120176410@gq.com 微信(QQ) : 2120176410 昵稱:粗糙的丸子 園齡:4個月 粉絲:0 關注:6< 2018年12月 > 日 一 二 三 四 五 六 25 26 27 28 29 30 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 1 2 3 4 5 搜索常用鏈接 我的隨筆 我的評論 我的參與 最新評論 我的標簽隨筆檔案 2018年12月 (5) 2018年11月 (5) 2018年10月 (1) 2018年9月 (7) 2018年8月 (1) 閱讀排行榜 1. 小紅書要求的技能掌握(熟悉RESTful服務,深刻理解mvc,oop, Aop概念)(29) 2. python題目-----search()和match()的區別(19) 3. mysql表操作之完整性約束(18) 4. css的三大特性繼承性,層疊行,優先級(17) 5. Json模塊dumps、loads、dump、load函數介紹(16)Copyright ?2018 粗糙的丸子 MyAuth.py-認證組件 class Books(APIView):# 列表中類名不能加括號authentication_classes = [LoginAuth, ]def get(self, request, *args, **kwargs):# 只要通過認證,就能取到當前登錄用戶對象的密碼,id等信息# print(request.query_params)print(request.user)# print(request.user.pwd)response = {'status': 100, 'msg': '查詢成功'}res = models.Book.objects.all()book_ser = MySerializer.BookSerializer(res, many=True)# 這個數據是需要返回給前臺的response['data'] = book_ser.data# print(book_ser.data)return JsonResponse(response, safe=False)# 登錄接口,不存數據庫的token認證 import jsonfrom day98 import settingsdef create_token(user_pk):md5 = hashlib.md5()md5.update(user_pk.encode('utf-8'))# 在setting里面全局配置一下,給token加鹽md5.update(settings.password.encode('utf-8'))hex = md5.hexdigest()token = '|'.join([hex, user_pk])# token=hex+'|'+user_infoprint(token)return tokenclass Login(APIView):authentication_classes = []# 登錄就是使用post,get是返回一個頁面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)user_info_json = json.dumps({'name': user.name, 'id': user.pk})# 生成vfvevberber|{'name': user.name, 'id': user.pk}的tokentoken = create_token(str(user.pk))# 登陸成功之后把登錄返回給他,以后就帶著token過來response['token'] = tokenexcept ObjectDoesNotExist as e:response['status'] = 101response['msg'] = '用戶名或密碼錯誤'except Exception as e:# 萬能異常,里面只要出錯,程序就會走到這里response['status'] = 102# response['msg'] = '未知錯誤'# 把整個錯誤信息轉換成str類型,賦值給e,一般在測試時使用這個response['msg'] = str(e)# 如果不寫safe=False,只能序列化字典形式,如果字典里面又套了列表,或者直接是一個列表,就必須寫safe=Falsereturn JsonResponse(response, safe=False)View.py-登錄接口 View.py-登錄接口?
轉載于:https://www.cnblogs.com/cao123/p/10116473.html
總結
以上是生活随笔為你收集整理的Rest-framework之drf认证组件,权限组件+不存数据库的token认证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 获取流水号
- 下一篇: Ssm网上考试系统 计算机专业毕设源码1