Django-rest-framework框架之路由组件,三大认证详解

今日内容概要

  • 路由组件
  • 登录接口编写
  • 三大认证之认证
  • 三大认证之权限
  • 三大认证之频率

路由组件

1.概念
只要继承了ViewSetMixin及其子类的视图类

2.自动生成路由

  • 自动生成路由的写法:
    (1)导入:from rest_framework.routers import StimpleRouter,DefaultRouter
    (2)实例化:router= SimpleRouter()
    (3)注册:router.register(‘user’,views.UserView,‘user’)
    user:该视图集的路由前缀
    view.UserView:视图集
    user:路由别名的前缀
    (4)加入到urlpatterns中
    方式一:urlpatterns+=router.urls
    方式二:path(‘’,include(router.urls))

3.自动生成的路由映射关系其实最初就已经固定不变的

  • 举个栗子:
    /books/------>get-------->list
    /books/------>post------->create
    /books/1------>get--------->retrieve

4.在视图类不写action装饰器的情况下,视图类中必须要有一下两点:

  • list,destroy,retrieve,create,update方法之一;
  • 必须是drf五个视图扩展类之一+GenericAPIView或9个视图子类,ModelViewSet

5.SimpleRouter和DefaultRouter对比
DefaultRouter比SimpleRouter多一个根路径,显示所有注册过的路由。

6.代码展示

  • 使用路由类给视图集生成了路由地址
# 必须是继承ModelViewSet的视图类才能自动生成路由
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
class StudentModelViewSet(ModelViewSet):
	queryset = Student.objects.all()
	serializer_class = StudentModelSerializer
# 这种方法不会自动生成,需要用action配置
	def login(self,request):
	"学生登录功能"
	print(self.action)
	return Response({"msg":"登录成功"})
  • 路由代码:
from django.urls import path,re_path
from .import views
urlpatterns = [
...]

"使用drf提供路由类router给视图集生成路由列表"
# 导入
from rest_framework.routers import DefaultRouter
# 实例化路由类
router = DefaultRouter()
# 注册视图集
router.register("路有前缀",视图集类)
router.register("router_stu",views.StudentModelViewSet)
# 把生成的路由列表追加到urlpatterns
urlpatterns += router.urls

上面的代码成功生成了路由地址(增,删,改,查一条,查多条的功能),但是不会自动生成我们在视图集自定义方法的路由。
引出下面的action装饰器。

7.action装饰器的使用

@action(methods=['GET','POST'],detail=True,url_path='login')
def login(self,request,pk)
  • 在视图函数中,会有一些其他名字的方法,必须使用action装饰器做映射
    (1)methods:支持的请求方式,列表
    (2)detail:默认都是False,控制生成的路由是/user/login还是/user/pk/login
    两者区别是是否带pk
    (3)url_path:控制生成的/user/后的路径是什么,如果不写,默认以方法命名
    /user/login/,一般跟函数名同名即可
    (4)url_name:别名,用于反向解析

登录接口编写

1…models.py

# 用户表
class User(mosels.Model):
	username = models.CharField(max_length=32)
	password = models.CharField(max_length=32)
	def __str__(self):
		return self.username

# 用户登录记录表
# 如何区分用户是否登录了?
class UserToken(models.Model):
   # SET_NULL   SET_DEFAULT   CASCADE  SET(函数内存地址)
   user = models.OneToOneField(to='User', on_delete=models.CASCADE)
   token = models.CharField(max_length=32, null=True)  # 用户如果没有登录,就是空,如果登录了,就有值,登录多次以最后一次为准

2.views.py

class UserView(ViewSet):
	authentication_class = []
	@action(methods=['POST',],detail=False,url_path='login')
	def login(self,request):
		# 取出前端传入的用户名密码,校验,通过,返回登录成功,失败就返回用户名密码错误
		username = request.data.get('username')
		password = request.data.get('password')
		user = User,objects.filter(username=username,password=password).first()
		if user:
		# 登录成功,不同人生成的token是不一样的,谁登录的就把token存到UserToken表中;
			token = str(uuid.uuid4())     # 生成一个永不重复的随机字符串
		# 存UserToken:如果没有记录,就是新增,如果有记录更新一下即可
		# 通过user去UserToken表中查数据,如果能查到,使用defaults的数据更新,如果查不到,直接通过user和defaults的数据新增
			UserToken.objects.update_or_create(defaults={'token':token},user=user)
			return Response({'code':100,'msg':'登录成功','token':token})
		else:
			return Response({'code':101,'msg':'用户名或密码错误'})

3.urls.py

from rest_framework.routers import SimpleRouter,DefaultRouter
router = SimpleRouter()
router.register('user',views.UserView,'user')
urlpatterns = [
	path('admin/',admin.site.urls),
	path('',include(router.urls)),
]

三大认证之认证

访问接口,必须登录后才能访问

1. 通过认证类完成,使用步骤:
(1)写一个认证类,继承BaseAuthentication;
(2)重写authenicate方法,在内部做认证;
(3)如果认证通过,返回2个值;
(4)认证不通过抛AuthenticationFailed异常;
(5)只要返回了两个值,在后续的request.user就是当前登录用户;
(6)如果想让某个视图类登录后才能访问

方式一:
	class BookView(ModelViewSet):
		authentication_classes = [LoginAuth,]
方式二:全局配置(settings.py中配置)
	REST_FRAMEWORK={
		'DEFAULT_AUTHENTICATION_CLASSES':['app01.auth.LoginAuth',]}

(7)局部禁用:

authentication_classes = []

2.认证类

from .models import UserToken
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed


class LoginAuth(BaseAuthentication):
   def authenticate(self, request):
       # 在这里做认证,校验用户是否登录(带了token,并且能查到,就是登录,返回两个值,否则就是没登录,抛异常)
       # 用户带的token从哪取?后端人员定的:放在请求地址中
       token = request.GET.get('token')
       # 通过token查询该token是否是在表中有记录
       user_token = UserToken.objects.filter(token=token).first()
       if user_token:
           return user_token.user, token  # 返回两个值,一个是当前登录用户,一个是token
       else:
           raise AuthenticationFailed('您没有登录')

三大认证之权限

1.概念

  • 认证:校验用户是否登录,登录认证;
  • 用户登录了,某个接口可能只有超级管理员才能访问,,普通用户不能访问;
  • 出版社的所有接口,必须登录,而且是超级管理员才能访问;

2.使用步骤

  • 第一步:写一个类,继承BasePermission;
  • 第二步:重写has_permission方法;
  • 第三步:再方法中校验用户是否有权限(request.user就是当前登录用户);
  • 第四步:如果有权限,返回True,没有权限,返回False;
  • 第五步:self.message是给前端的提示信息;
  • 第六步:局部使用,全局使用,局部禁用。
全局使用:
REST_FRAMEWORK={
   "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
   "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",]
}

局部使用:
# 局部使用只需要在视图类里加入:
permission_classes = [UserPermission,]

3.权限类

from rest_framwork.permissions import BasePermission
class UserTypePermisssion(BasePermission):
	def has_permission(self,request,view):
	# 只有超级管理员有权限
		if request.user.user_type == 1:
			return True   # 有权限
		else:
			# self,message = '普通用户和某些用户都没有权限'  # 返回给前端的提示是什么样的
			# 使用了choice后,user.user_type 拿到的是数字类型,想变成字符串user.get_user_type_display()
			# self.message = '您是:%s 用户,您没有权限' % request.user.get_user_type_display()
			return False   # 没有权限

三大认证之频率

1.概念
无论是否登录和是否有权限,都要限制访问的频率,比如一分钟访问3次
2.使用步骤

  • 第一步:写一个类:继承SimpleRateThrottle;
  • 第二步:重写get_cache_key,返回唯一的字符串,会以这个字符串作为频率限制;
  • 第三步:写一个类属性scop=‘随意些’,必须要跟配置文件对象;
  • 第四步:配置文件中写:
'DEFAULT_THROTTLE_RATES':{
'随意写''3/m'       # 3/h     3/s      3/d
}
  • 第五步:局部配置,全局配置,局部禁用。
全局使用:
REST_FRAMEWORK = {
   'DEFAULT_THROTTLE_CLASSES':['app01.utils.MyThrottles',],
}

局部使用:
#在视图类里使用
throttle_classes = [MyThrottles,]

3.频率类

from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
class MyThrottling(SimpleRateThrottle):  # 我们继承SimpleRateThrottle去写,而不是继承BaseThrottle去写
# 类属性,这个类属性可以随意命名,但要跟配置文件对应
scope = 'luffy'
def get_cache_key(self,request,view):
	# 返回什么,频率就以什么做限制
	# 可以通过用户id限制
	# 可以通过ip地址限制
	return request.META.get('REMOTE_ADDR')

settings.py文件

REST_FRAMEWORK = {
   'DEFAULT_THROTTLE_CLASSES':['app01.throttling.MyThrottling'],
   'DEFAULT_THROTTLE_RATES': {
       'luffy': '3/m'
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值