DRF认证权限频率

目录

编写登录接口

认证

编写认证类

全局使用

局部使用

内置的认证类

on_delete相关

权限

编写权限类

全局使用

局部使用

局部禁用

内置权限类

 频率

编写频率类

配置文件

局部配置

内置的频率类

认证源码分析

权限源码分析

频率源码分析


编写登录接口

models.py

from django.db import models


# Create your models here.

class User(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=32)


class UserToken(models.Model):
    token = models.CharField(max_length=32)
    user = models.OneToOneField(to='User', on_delete=models.CASCADE)

views.py

from .serializer import UserSerializer
from .models import User, UserToken
import uuid
from django.contrib.auth.hashers import make_password


class UserView(ModelViewSet):
    queryset = User
    serializer_class = UserSerializer

    @action(methods=['POST'], detail=False)
    def login(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            username = ser.data.get('username')
            password = ser.data.get('password')
            user = User.objects.filter(username=username, password=password).first()
            if user:
                # 生成唯一随机token
                token = uuid.uuid4()
                # 用户登陆过就更新没登录就新增UserToken表
                UserToken.objects.update_or_create(defaults={'token': token}, user=user)
                return Response({'code': 100, 'msg': '登陆成功'})
            return Response({'code': 101, 'msg': '用户名或密码错误'})
        return Response(ser.errors)

serializer.py

from .models import User
from rest_framework import serializers


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

urls.y

from django.contrib import admin
from django.urls import path
from rest_framework.routers import DefaultRouter
from app01 import views

router = DefaultRouter()

router.register('user', views.UserView, 'user')

urlpatterns = [
    path('admin/', admin.site.urls),
]

urlpatterns.extend(router.urls)

认证

访问接口时, 需要登录后才能访问

编写认证类

1. 新建一个认证py文件, 写一个认证类, 继承BaseAuthentication

2.规定通过路由后缀传递token值, 【如果token值可以查询到, 说明可以登录】

3. 重写authenticate方法

4. 验证成功返回两个值【当前登录用户和token]

5. 验证失败则抛出AuthenticationFailed异常

6. 只要验证成功,后续requestuser就是当前登陆用户

userauth.py

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


class UserAuth(BaseAuthentication):
    def authenticate(self, request):
        token = request.GET.get('token')
        token_obj = UserToken.objects.filter(token=token).first()
        if token_obj:
            return token_obj.user, token
        else:
            raise AuthenticationFailed('没有登陆')

全局使用

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ['app01.userauth.UserAuth']
}

局部使用

class UserView(ModelViewSet):
    queryset = User.objects
    serializer_class = UserSerializer
    authentication_classes = [UserAuth]

局部禁用将authentication_classes设置为空即可。

内置的认证类

    -BasicAuthentication
    -RemoteUserAuthentication
    -SessionAuthentication:session认证,建议自己写
        -如果前端带着cookie过来,经过session的中间件,如果登录了,在request.user中就有当前登录用户
        -drf没有限制是否登录
        -加了这个认证,如果没有登录,就不允许往后访问了
    -TokenAuthentication:jwt认证,建议自己写
    -建议自己写

on_delete相关

当一个由ForeignKey引用的对象被删除时, django将模拟on_delete参数所指定的SQL约束的行为。 例如: 有一个可为空的ForeignKey,并且你希望当被引用的对象被删除时他被设置为空

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.CharField(max_length=32)
    publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True)

1. models.CASCADE

级联操作, 当主表中被连接的一条数据删除时,从表中所有与之关联的数据同时被删除

2. models.SET_NULL

当主表中的一行数据删除时, 从表中与之关联的数据的相关字段设置为null, 此时注意定义外键时, 这个字段必须可以允许为空

3. models.PROTECT

当主表中的一行数据删除时,由于从表中相关字段是受保护的外键 , 所以都不允许删除

4. models.SET_DEFAULT

当主表中的一行数据删除时,从表中所有的关联数据的关联字段设置为默认值, 此时主要定义外键时, 这个外键字段应该有一个默认值

5. models.SET()

【当主表中的一条数据删除时, 从表中所有的关联数据字段设置为SET()中设置的值, 与models.SET_DEFAULT相似, 只不过此时从表中的相关字段不需要设置default参数】

将ForeignKey设置为传递给Set()的值, 如果传入了一个可调配对象,则设置为调用它的结果, 大多数情况下,为了避免在导入models,py时执行查询, 需要传入一个可调用对象

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models

def get_sentinel_user():
    return get_user_model().objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET(get_sentinel_user),
)

6. models.DO_NOTHING

什么都不做, 一切都看数据库级别的约束, 注意数据库级别的默认约束为RESTRICT , 这个约束与jango中的models.PROTECT相似

7.models.RESTRICT

通过引发RestrictError(django.db.IntegrityError的一个子类)来防止删除被引用的对象, 与PROTECT不同的是, 如果被引用的对象也引用了一个在统一操作中被删除的不同对象, 但通过CASCADE关系,则允许删除被引用的对象。

class Artist(models.Model):
name = models.CharField(max_length=10)

class Album(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)

class Song(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    album = models.ForeignKey(Album, on_delete=models.RESTRICT)

Artist可以被删除, 即使这意味着删除被Song引用的Album,因为Song也通过级联关系引用Artist本身, 例如

>>> artist_one = Artist.objects.create(name='artist one')
>>> artist_two = Artist.objects.create(name='artist two')
>>> album_one = Album.objects.create(artist=artist_one)
>>> album_two = Album.objects.create(artist=artist_two)
>>> song_one = Song.objects.create(artist=artist_one, album=album_one)
>>> song_two = Song.objects.create(artist=artist_one, album=album_two)
>>> album_one.delete()
# Raises RestrictedError.
>>> artist_two.delete()
# Raises RestrictedError.
>>> artist_one.delete()
(4, {'Song': 2, 'Album': 1, 'Artist': 1})

权限

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值