Python正课146 —— DRF 进阶7 JWT补充、基于权限的角色控制、django缓存

python

https://www.cnblogs.com/xuexianqi/p/13307390.html

1.控制用户登录后才能访问,和不登录就能访问

# 1 控制用户登录后才能访问,和不登录就能访问

from rest_framework.permissions import IsAuthenticated

class OrderAPIView(APIView):# 登录才能

authentication_classes = [JSONWebTokenAuthentication,]

# 权限控制

permission_classes = [IsAuthenticated,]

def get(self,request,*args,**kwargs):

return Response('这是订单信息')

class UserInfoAPIView(APIView):# 不登录就可以

authentication_classes = [JSONWebTokenAuthentication,]

# 权限控制

# permission_classes = [IsAuthenticated,]

def get(self,request,*args,**kwargs):

return Response('UserInfoAPIView')

2.控制登录接口返回的数据格式

# 2 控制登录接口返回的数据格式

-第一种方案,自己写登录接口

-第二种写法,用内置,控制登录接口返回的数据格式

-jwt的配置信息中有这个属性

'JWT_RESPONSE_PAYLOAD_HANDLER':

'rest_framework_jwt.utils.jwt_response_payload_handler',

-重写jwt_response_payload_handler,配置成咱们自己的

3.自定义基于jwt的权限类

# 3 自定义基于jwt的权限类

from rest_framework.authentication import BaseAuthentication # 基于它

from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication # 基于它

from rest_framework.exceptions import AuthenticationFailed

# from rest_framework_jwt.authentication import jwt_decode_handler

from rest_framework_jwt.utils import jwt_decode_handler # 跟上面是一个

import jwt

from api import models

# class MyJwtAuthentication(BaseAuthentication):

# def authenticate(self, request):

# jwt_value=request.META.get('HTTP_AUTHORIZATION')

# if jwt_value:

# try:

# #jwt提供了通过三段token,取出payload的方法,并且有校验功能

# payload=jwt_decode_handler(jwt_value)

# except jwt.ExpiredSignature:

# raise AuthenticationFailed('签名过期')

# except jwt.InvalidTokenError:

# raise AuthenticationFailed('用户非法')

# except Exception as e:

# # 所有异常都会走到这

# raise AuthenticationFailed(str(e))

# # 因为payload就是用户信息的字典

# print(payload)

# # return payload, jwt_value

# # 需要得到user对象,

# # 第一种,去数据库查

# # user=models.User.objects.get(pk=payload.get('user_id'))

# # 第二种不查库

# user=models.User(id=payload.get('user_id'),username=payload.get('username'))

# return user,jwt_value

# # 没有值,直接抛异常

# raise AuthenticationFailed('您没有携带认证信息')

class MyJwtAuthentication(BaseJSONWebTokenAuthentication):

def authenticate(self, request):

jwt_value=request.META.get('HTTP_AUTHORIZATION')

if jwt_value:

try:

#jwt提供了通过三段token,取出payload的方法,并且有校验功能

payload=jwt_decode_handler(jwt_value)

except jwt.ExpiredSignature:

raise AuthenticationFailed('签名过期')

except jwt.InvalidTokenError:

raise AuthenticationFailed('用户非法')

except Exception as e:

# 所有异常都会走到这

raise AuthenticationFailed(str(e))

user=self.authenticate_credentials(payload)

return user,jwt_value

# 没有值,直接抛异常

raise AuthenticationFailed('您没有携带认证信息')

4.手动签发token(多方式登录)

# 使用用户名,手机号,邮箱,都可以登录#

# 前端需要传的数据格式

{

"username":"lqz/1332323223/33@qq.com",

"password":"lqz12345"

}

# 视图

from rest_framework.views import APIView

from rest_framework.viewsets import ViewSetMixin, ViewSet

from app02 import ser

class Login2View(ViewSet): # 跟上面完全一样

def login(self, request, *args, **kwargs):

# 1 需要 有个序列化的类

login_ser = ser.LoginModelSerializer(data=request.data,context={'request':request})

# 2 生成序列化类对象

# 3 调用序列号对象的is_validad

login_ser.is_valid(raise_exception=True)

token=login_ser.context.get('token')

# 4 return

return Response({'status':100,'msg':'登录成功','token':token,'username':login_ser.context.get('username')})

# 序列化类

from rest_framework import serializers

from api import models

import re

from rest_framework.exceptions import ValidationError

from rest_framework_jwt.utils import jwt_encode_handler,jwt_payload_handler

class LoginModelSerializer(serializers.ModelSerializer):

username=serializers.CharField() # 重新覆盖username字段,数据中它是unique,post,认为你保存数据,自己有校验没过

class Meta:

model=models.User

fields=['username','password']

def validate(self, attrs):

print(self.context)

# 在这写逻辑

username=attrs.get('username') # 用户名有三种方式

password=attrs.get('password')

# 通过判断,username数据不同,查询字段不一样

# 正则匹配,如果是手机号

if re.match('^1[3-9][0-9]{9}$',username):

user=models.User.objects.filter(mobile=username).first()

elif re.match('^.+@.+$',username):# 邮箱

user=models.User.objects.filter(email=username).first()

else:

user=models.User.objects.filter(username=username).first()

if user: # 存在用户

# 校验密码,因为是密文,要用check_password

if user.check_password(password):

# 签发token

payload = jwt_payload_handler(user) # 把user传入,得到payload

token = jwt_encode_handler(payload) # 把payload传入,得到token

self.context['token']=token

self.context['username']=user.username

return attrs

else:

raise ValidationError('密码错误')

else:

raise ValidationError('用户不存在')

5.jwt的配置参数

# jwt的配置

import datetime

JWT_AUTH={

'JWT_RESPONSE_PAYLOAD_HANDLER':'app02.utils.my_jwt_response_payload_handler',

'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), # 过期时间,手动配置

}

二:基于角色的权限控制(django内置auth体系)

# RBAC :是基于角色的访问控制(Role-Based Access Control ),公司内部系统

# django的auth就是内置了一套基于RBAC的权限系统

# django中

# 后台的权限控制(公司内部系统,crm,erp,协同平台)

user表

permssion表

group表

user_groups表是user和group的中间表

group_permissions表是group和permssion中间表

user_user_permissions表是user和permission中间表

# 前台(主站),需要用三大认证

# 演示:

三:django缓存

# 前端混合开发缓存的使用

-缓存的位置,通过配置文件来操作(以文件为例)

-缓存的粒度:

-全站缓存

中间件

MIDDLEWARE = [

'django.middleware.cache.UpdateCacheMiddleware',

。。。。

'django.middleware.cache.FetchFromCacheMiddleware',

]

CACHE_MIDDLEWARE_SECONDS=10 # 全站缓存时间

-单页面缓存

在视图函数上加装饰器

from django.views.decorators.cache import cache_page

@cache_page(5) # 缓存5s钟

def test_cache(request):

import time

ctime=time.time()

return render(request,'index.html',context={'ctime':ctime})

-页面局部缓存

{% load cache %}

{% cache 5 'name' %} # 5表示5s钟,name是唯一key值

{{ ctime }}

{% endcache %}

# 前后端分离缓存的使用

- 如何使用

from django.core.cache import cache

cache.set('key',value可以是任意数据类型)

cache.get('key')

-应用场景:

-第一次查询所有图书,你通过多表联查序列化之后的数据,直接缓存起来

-后续,直接先去缓存查,如果有直接返回,没有,再去连表查,返回之前再缓存

四:补充

1.补充base64使用

# base64编码和解码

#md5固定长度,不可反解

#base63 变长,可反解

#编码(字符串,json格式字符串)

import base64

import json

dic={'name':'lqz','age':18,'sex':'男'}

dic_str=json.dumps(dic)

ret=base64.b64encode(dic_str.encode('utf-8'))

print(ret)

# 解码

# ret是带解码的串

ret2=base64.b64decode(ret)

print(ret2)

以上是 Python正课146 —— DRF 进阶7 JWT补充、基于权限的角色控制、django缓存 的全部内容, 来源链接: utcz.com/z/389276.html

回到顶部