一、创建LoginAuth类完成认证过程
使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,'会员'),(2,'超级用户'))
# 指定choice,可以快速的通过数字,取出文字
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
迁移数据库
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__'
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):
# 生成一个md5对象
md5 = hashlib.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 = []
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)
# 校验通过,登录成功,生成一个随机字符串(身份标识)token
token = get_token(name)
# 保存到数据库
# update_or_create更新或者创建
models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
response['token'] = token
except ObjectDoesNotExist as e:
response['status'] = 101
response['msg'] = '用户名或密码错误'
except Exception as e:
response['status'] = 102
# response['msg']='未知错误'
response['msg'] = str(e)
return JsonResponse(response, safe=False)
from rest_framework import exceptions
class LoginAuth():
# 函数名必须叫这个名字,接收必须两个参数,第二个参数是request对像
def authenticate(self, request):
# 从request对像中取出token (也可以从其他地方中取)
token = request.query_params.get('token')
# 去数据库中查询
ret = models.UserToken.objects.filter(token=token)
if ret:
# 可以查到,说明认证通过,返回空
return None
# 否则会报异常
raise exceptions.APIException('认证失败')
from rest_framework.request import Request
# class Books(APIView):
# # 列表中类型不能加括号
# authentication_classes = [LoginAuth, ]
#
# def get(self, request, *args, **kwargs):
# response = {'status': 100, 'msg': '查询成功'}
# # 必须登录以后,才能获取数据
# # 取出token,取数据库验证,是否登录
# token = request.query_params.get('token')
# ret = models.UserToken.objects.filter(token=token)
# if ret:
# # 认证通过,是登录用户
# ret = models.Book.objects.all()
# book_ser = MySerializer.BookSerializer(ret, many=True)
# response['data'] = book_ser.data
# else:
# response['status'] = 101
# response['msg'] = '认证不通过'
# return JsonResponse(response, safe=False)
# 与上面的Books类功能一样,但比上面的那个更加简洁。
class Books(APIView):
# 列表中类型不能加括号
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)
数据库中添加数据测试:
使用Postman测试:
功能:登录后方可查看书的详情信息
使用数据库中的用户名与密码登录服务:
使用token登录来验证查询书的详情信息
若是token验证不成功,就会返回:
二、认证组件的全局使用与局部使用
urls.py、models.py、不变
局部使用:
views.py
from app01.MyAuth import LoginAuth
class Books(APIView):
# 列表中类型不能加括号
# 认证组件局部使用
authentication_classes = [LoginAuth, ]
# 认证组件,局部禁用 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)
from rest_framework import exceptions
from app01 import models
# 用dnf 认证,写一个类
class LoginAuth():
# 函数名必须叫这个名字,接收必须两个参数,第二个参数是request对像
def authenticate(self, request):
# 从request对像中取出token (也可以从其他地方中取)
token = request.query_params.get('token')
# 去数据库中查询
ret = models.UserToken.objects.filter(token=token)
if ret:
# 可以查到,说明认证通过,返回空
return None
# 否则会报异常
raise exceptions.APIException('认证失败')
-全局使用
-在setting中配置:
使django支持 framework
在settings.py中的INSTALLED_APPS字段添加:
"rest_framework"
REST_FRAMEWORK={
'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',],
}
-局部禁用,views.py中有:
认证组件,局部禁用 authentication_classes = []
三、权限组建
用户身份不同,权限也不同
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()),
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):
# 生成一个md5对象
md5 = hashlib.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 = []
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)
# 校验通过,登录成功,生成一个随机字符串(身份标识)token
token = get_token(name)
# 保存到数据库
# update_or_create更新或者创建
models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
response['token'] = token
except ObjectDoesNotExist as e:
response['status'] = 101
response['msg'] = '用户名或密码错误'
except Exception as e:
response['status'] = 102
# response['msg']='未知错误'
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):
# 列表中类型不能加括号
# 认证组件局部使用
# authentication_classes = [LoginAuth, ]
# 认证组件,局部禁用 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)
# 只能超级用户可以查看作者详情,其他人不能看
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)
# 认证组件全局使用
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 认证,写一个类
class LoginAuth(BaseAuthentication):
# 函数名必须叫这个名字,接收必须两个参数,第二个参数是request对像
def authenticate(self, request):
# 从request对像中取出token (也可以从其他地方中取)
token = request.query_params.get('token')
print(token)
# 去数据库中查询
ret = models.UserToken.objects.filter(token=token).first()
print(ret)
if ret:
# 可以查到,说明认证通过,返回空
return ret.user, ret
# 否则会报异常
raise exceptions.APIException('认证失败')
from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
# message是出错显示的中文
message = '没权限查看'
def has_permission(self, request,view):
print(request.user)
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 True
else:
return False
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()
from django.db import models
# Create your models here.
# 用户信息
class UserInfo(models.Model):
name = models.CharField(max_length=32)
# 写choice
user_choice = ((0, '普通用户'), (1, '会员'), (2, '超级用户'))
# 指定choice,可以快速的通过数字,取出文字
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
数据库中添加数据:
使用Postman来登录用户获取token:
使用Postman 中的"s_jun"(只有超级用户有权限查看,其他人没有权限查看)用户的token测试:
其他用户的token查看:
使用postman 查看用户身份类型以及中文方式显示
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。