dango框架学习:四十二.django-rest-framework.权限认证(permission)
前言
當(dāng)用戶登錄后,才有操作當(dāng)前用戶的權(quán)限,只可以操作自己的賬戶,不能操作別人的賬戶,怎樣實(shí)現(xiàn)?這就需要用到權(quán)限認(rèn)證。
authentication是身份認(rèn)證,用于判斷當(dāng)前用戶的登錄方式是哪種認(rèn)證方式。
permission是權(quán)限認(rèn)證,判斷哪些用戶有操作權(quán)限
authentication身份認(rèn)證
身份認(rèn)證是將收到的請求和一組標(biāo)識證書(如用戶密碼,令牌)進(jìn)行關(guān)聯(lián)的一種機(jī)制,遍以權(quán)限和策略可以根據(jù)這個(gè)標(biāo)識證書來決定是否允許該請求,因此身份認(rèn)證驗(yàn)證發(fā)生在驗(yàn)證權(quán)限和限制檢查之前。
當(dāng)收到的請求通過身份驗(yàn)證時(shí):
request.user的屬性會設(shè)置為django.contrib.auth.User對象,即我們登陸的對象(我們定義用戶繼承于User)。
request.auth的屬性會設(shè)置為對應(yīng)的Token(如果帶有Token)或者None(如果不帶有Token)。
當(dāng)收到請求身份驗(yàn)證失敗時(shí):
request.user的屬性會設(shè)置為django.contrib.auth.models.AnonymousUser對象。
request.auth會設(shè)置為None。
django rest framework權(quán)限和認(rèn)證有四種方式:
BasicAuthentication 此身份驗(yàn)證方案使用HTTP基本身份驗(yàn)證,根據(jù)用戶的用戶名和密碼進(jìn)行簽名。基本身份驗(yàn)證通常僅適用于測試
TokenAuthentication 此身份驗(yàn)證方案使用基于令牌的簡單HTTP身份驗(yàn)證方案。令牌認(rèn)證適用于客戶端 - 服務(wù)器設(shè)置,例如本機(jī)桌面和移動(dòng)客戶端。
SessionAuthentication 此身份驗(yàn)證方案使用Django的默認(rèn)會話后端進(jìn)行身份驗(yàn)證。會話身份驗(yàn)證適用于與您的網(wǎng)站在同一會話上下文中運(yùn)行的AJAX客戶端。
RemoteUserAuthentication 此身份驗(yàn)證方案允許您將身份驗(yàn)證委派給Web服務(wù)器,該服務(wù)器設(shè)置REMOTE_USER 環(huán)境變量。
permission權(quán)限認(rèn)證
權(quán)限檢查通常使用request.user和request.auth屬性中的身份驗(yàn)證信息來確定是否應(yīng)允許傳入請求。
當(dāng)權(quán)限檢查失敗時(shí),將根據(jù)一下規(guī)則返回Http403 Forbidden或Http 401 Unauthorized:
如果收到的請求身份驗(yàn)證通過,但是權(quán)限驗(yàn)證失敗,則返回Http403 Forbidden;
如果收到的請求身份驗(yàn)證失敗,且最高優(yōu)先級驗(yàn)證類不能使用WWW-Authenticate請求頭,則返回403Forbidden;
如果收到的請求身份驗(yàn)證失敗,且最高優(yōu)先級驗(yàn)證類能使用WWW-Authenticate請求頭,則返回401 Unauthorized;
權(quán)限級別也有四種:
AllowAny 允許所有用戶
IsAuthenticated 表示僅僅允許身份驗(yàn)證通過的用戶訪問,其他用戶無法訪問。
IsAdminUser 表示僅僅允許管理員用戶訪問,普通用戶無法訪問。
IsAuthenticatedOrReadOnly 表示僅僅允許身份驗(yàn)證通過的用戶訪問,或者只允許只讀請求(GET請求)訪問。
settings.py相關(guān)配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ke25',
'xadmin',
'rest_framework',
'rest_framework.authtoken',
]
settings.py文件可以全局配置,會對所有的接口生效,REST_FRAMEWORK添加權(quán)限認(rèn)證方式和身份認(rèn)證方式
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication', # token認(rèn)證
),
# 權(quán)限認(rèn)證 全局配置
'DEFAULT_PERMISSION_CLASSES':(
#'rest_framework.permissions.IsAuthenticated',# IsAuthenticated 僅通過認(rèn)證的用戶
'rest_framework.permissions.AllowAny',# AllowAny 允許所有用戶
#'rest_framework.permissions.IsAdminUser',# IsAdminUser 僅管理員用戶
#'rest_framework.permissions.IsAuthenticatedOrReadOnly', # IsAuthenticatedOrReadOnly 認(rèn)證的用戶可以完全操作,否則只能get讀取 ),
)
}
局部添加權(quán)限
局部權(quán)限只針對當(dāng)前的接口生效,登錄生成token,登錄允許所有已有用戶登錄,設(shè)置局部權(quán)限:
permission_classes = (AllowAny,) #允許所有用戶
from . import models
from django.shortcuts import render
from django.http import JsonResponse
from django.shortcuts import HttpResponse
from rest_framework.authtoken.models import Token
from django.contrib import auth
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated,AllowAny
from rest_framework.authentication import TokenAuthentication
from rest_framework import serializers
class LoginViewSet(APIView):
'''登錄方法'''
permission_classes = (AllowAny,) #允許所有用戶
def post(self, request, *args, **kwargs):
username = request.data.get('username')
password = request.data.get('password')
user = auth.authenticate(username=username, password=password)
if not user:
return JsonResponse({"code": 0,
"msg": "用戶名或密碼不對!"})
# 刪除原有的Token
old_token = Token.objects.filter(user=user)
old_token.delete()
# 創(chuàng)建新的Token
token = Token.objects.create(user=user)
return JsonResponse({"code": 0,
"msg": "login success!",
"username": user.username,
"token": token.key})
登錄成功后,關(guān)聯(lián)Card表,添加authentication身份認(rèn)證permission權(quán)限認(rèn)證
authentication_classes = (TokenAuthentication,) # token認(rèn)證 permission_classes = (IsAuthenticated,) # # IsAuthenticated 僅通過認(rèn)證的用戶
views.py代碼如下:
class CardAPISerializer(serializers.ModelSerializer):
'''序列化數(shù)據(jù)的類,根據(jù)model表來獲取字段'''
class Meta:
model = models.Card
fields = '__all__'
# fields = ('card_id','card_user')
class CardListAPIView(APIView):
'''REST framework的APIView實(shí)現(xiàn)獲取card列表 '''
'''return list of all user'''
authentication_classes = (TokenAuthentication,)#token認(rèn)證
permission_classes = (IsAuthenticated,)#IsAuthenticated僅通過認(rèn)證的用戶
def get(self, request, format=None):
cards = models.Card.objects.all()
serializer = CardAPISerializer(cards,many=True)
return JsonResponse({"code":0,
"msg":"查詢成功",
"data":serializer.data})
def post(self,request,format=None):
'''create Card 反序列化'''
verify_data = CardAPISerializer(data=request.data) # 只改這里
if verify_data.is_valid(): # 判斷數(shù)據(jù)是否合法
verify_data.save()
return JsonResponse({"code": 0,
"msg": "創(chuàng)建成功",
"data": request.data})
else:
return JsonResponse({"code": 0,
"msg": "創(chuàng)建成功",
"data":'request data invaild %s'% verify_data.errors})
models.py
from django.db import models
# Create your models here.
class Card(models.Model):
card_id = models.IntegerField(verbose_name="卡號")
card_user = models.CharField(verbose_name='姓名',max_length=128)
add_time = models.DateTimeField(verbose_name='日期',auto_now_add=True)
class Meta:
verbose_name = '銀行卡賬戶'
verbose_name_plural = '銀行卡賬戶信息'
def __str__(self):
return self.card_id
urls.py
url(r'^api/v1/login/$', vie.LoginViewSet.as_view()), url(r'api/v1/cardlist/$', vie.CardListAPIView.as_view()),
接口關(guān)聯(lián)測試
登錄接口
登錄接口response,獲取token值
將token添加到cardlist接口請求頭
如果token錯(cuò)誤,或者沒有token就會出現(xiàn)401 Unauthorized
總結(jié)
以上是生活随笔為你收集整理的dango框架学习:四十二.django-rest-framework.权限认证(permission)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图灵学院-微服务11-分布式链路跟踪Sl
- 下一篇: 如何清除DNS缓存,使用cmd命令清理D