Django restframework permission 权限

权限一般与认证放到一起,权限检查一般是检查 request.user 和 request.auth属性中的身份验证信息来确定是否允许传入请求。权限用于授予或拒绝不同类别的用户对不同API的访问。最简单的权限是允许所有经过身份认证的用户,这对应着IsAuthenticated类。

如何确定权限

REST框架中的权限和认证一样:为权限类列表。

在运行视图主体之前,将检查列表中的每个权限。如果任何权限检查失败,则将引发exceptions.PermissionDeniedexceptions.NotAuthenticated异常,并且视图主体将不运行。

if request.method in permissions.SAFE_METHODS: # read-only
            return True

设置权限策略:第一个样例

可以使用该DEFAULT_PERMISSION_CLASSES设置在全局范围内设置默认权限策略。例如。

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}

如果未指定,则此设置默认为允许无限制访问:

'DEFAULT_PERMISSION_CLASSES': [
   'rest_framework.permissions.AllowAny',
]

您还可以使用APIView基于类的视图基于每个视图或每个视图集设置身份验证策略。

from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)

 自定义权限:第二个样例

step1:APP目录下生成utils目录,utils目录下生成permission.py文件,并编写认证类代码:

To implement a custom permission, override BasePermission and implement either, or both, of the following methods:

  • .has_permission(self, request, view)
  • .has_object_permission(self, request, view, obj)

The methods should return True if the request should be granted access, and False otherwise.

If you need to test if a request is a read operation or a write operation, you should check the request method against the constant SAFE_METHODS, which is a tuple containing 'GET''OPTIONS' and 'HEAD'. For example:

if request.method in permissions.SAFE_METHODS:
    # Check permissions for read-only request
else:
    # Check permissions for write request
from rest_framework.permissions import BasePermission

class SVIPPremission(BasePermission):
    message = "必须是SVIP才能访问"
    def has_permission(self,request,view):
        if request.user.user_type != 3:
            return False
        return True

step2:DEFAULT_AUTHENTICATION_CLASSES设置全局设置默认身份验证方案,例如:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'pert.utils.authenticate.FirstAuthenticate',
        'pert.utils.authenticate.MyAuthenticate',
    ],
    "DEFAULT_PERMISSION_CLASSES": ['pert.utils.permission.MyPermission'],
}

step3:在Views文件中使用身份验证方案(并编号URL文件)

#urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url

from pert.views import AuthView
from pert.views import OrderView
from pert.views import UserInfoView
from pert.views import Example

urlpatterns = [
    path('admin/', admin.site.urls),
    path('example', Example.as_view()),
    path('api/v1/auth/', AuthView.as_view()),
    path('api/v1/order/', OrderView.as_view()),
    path('api/v1/info/', UserInfoView.as_view())
]

#views.py
from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from django.views import View

from rest_framework import exceptions
from rest_framework.views import APIView
from rest_framework.parsers import JSONParser
from rest_framework.authentication import BaseAuthentication, SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from pert import models
import json

ORDER_DICT = {
    1:{
        'name':'apple',
        'price':15
    },
    2:{
        'name':'dog',
        'price':100
    }
}

def md5(user):
    import hashlib
    import time

    # 当前时间,相当于生成一个随机的字符串
    ctime = str(time.time())

    # token加密
    m = hashlib.md5(bytes(user, encoding='utf-8'))
    m.update(bytes(ctime, encoding='utf-8'))
    return m.hexdigest()


class AuthView(View):
    authentication_classes = []
    permission_classes = []
    def get(self, request, *args, **kwargs):
        ret = {'code': 1000, 'msg': 'success', 'name': 'get method'}
        ret = json.dumps(ret, ensure_ascii=False)
        return HttpResponse(ret)

    def post(self, request, *args, **kwargs):
        ret = {'code': 1000, 'msg': None}
        try:
            data = JSONParser().parse(request)
            user = data["username"]
            pwd = data["password"]
            # user = request.data.get("username")
            # pwd = request.data.get("password")
            obj = models.UserInfo.objects.filter(username=user).first()

            if not obj:
                obj = models.UserInfo.objects.create(username=user, password=pwd)
                ret['code'] = 1001
                ret['msg'] = '创建用户成功'

            # 为用户创建token
            token = md5(user)
            # 存在就更新,不存在就创建
            models.UserToken.objects.update_or_create(user=obj, defaults={'token': token})
            ret['token'] = token
        except Exception as e:
            ret['code'] = 1002
            ret['msg'] = '请求异常'
        return JsonResponse(ret)


import pert.utils.authenticate as authenticate
import pert.utils.permission as permission
class OrderView(APIView):
    permission_classes = []
    def get(self, request, *args, **kwargs):
        print(str(request.user))
        ret = {
            'code': 1024,
            'msg': '订单获取成功',
        }
        try:
            ret['data'] = ORDER_DICT
        except Exception as e:
            pass
        return JsonResponse(ret)


class UserInfoView(APIView):

    def get(self, request, *args, **kwargs):
        print(request.user)
        return HttpResponse('SVIP用户信息')

step4:验证(修改数据库usertype)

最后permission权限是根据认证返回的user 和auth进行权限的判断的,需要注意

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值