一、創(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è)試:
使用Postman測(cè)試:
功能:登錄后方可查看書的詳情信息
使用數(shù)據(jù)庫(kù)中的用戶名與密碼登錄服務(wù):
使用token登錄來(lái)驗(yàn)證查詢書的詳情信息
若是token驗(yàn)證不成功,就會(huì)返回:
二、認(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ù):
使用Postman來(lái)登錄用戶獲取token:
使用Postman 中的"s_jun"(只有超級(jí)用戶有權(quán)限查看,其他人沒(méi)有權(quán)限查看)用戶的token測(cè)試:
其他用戶的token查看:
使用postman 查看用戶身份類型以及中文方式顯示
分享文章: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)