2015-09-29 73 views

回答

0

在保存您的api文件的文件夾中,創建另一個文件來保存您的自定義驗證類,如authentication.py。然後在您的設置下,在DEFAULT_AUTHENTICATION_CLASSES下,指向您的自定義認證類。

8

如何在DRF中實現自定義認證方案?

要實施自定義認證方案,我們需要繼承DRF的BaseAuthentication類並覆蓋.authenticate(self, request)方法。

如果認證成功,該方法應返回(user, auth)的二元組,否則返回None。在某些情況下,我們可能會從.authenticate()方法中引發AuthenticationFailed例外。

(來自DRF docs)實施例:

假設我們要驗證的任何傳入的請求如在名爲'X_USERNAME'定製請求頭由username給出的用戶。

第1步:創建自定義驗證類

爲了做到這一點,我們將在my_app創建authentication.py文件。

# my_app/authentication.py 
from django.contrib.auth.models import User 
from rest_framework import authentication 
from rest_framework import exceptions 

class ExampleAuthentication(authentication.BaseAuthentication): 
    def authenticate(self, request): 
     username = request.META.get('X_USERNAME') # get the username request header 
     if not username: # no username passed in request headers 
      return None # authentication did not succeed 

     try: 
      user = User.objects.get(username=username) # get the user 
     except User.DoesNotExist: 
      raise exceptions.AuthenticationFailed('No such user') # raise exception if user does not exist 

     return (user, None) # authentication successful 

步驟2:指定自定義驗證類

,我們需要在我們的DRF設置來定義這個認證類創建自定義的驗證類之後。這樣做,所有請求都將基於此認證方案進行認證。

'DEFAULT_AUTHENTICATION_CLASSES': (  
    'my_app.authentication.ExampleAuthentication', # custom authentication class 
    ... 
), 

注:如果你想使用這個定製驗證級上按次基礎或每個視圖集基礎,而不是在全球層面上,你可以明確地在你的意見確定此身份驗證類。

class MyView(APIView): 

    authentication_classes = (ExampleAuthentication,) # specify this authentication class in your view 

    ... 
+0

可以請你就如何使用這種使用curl的例子嗎? – momokjaaaaa

+1

@momokjaaaaa檢查此SO鏈接是否在POST請求中發送標頭。 http://stackoverflow.com/questions/356705/how-to-send-a-header-using-a-http-request-through-a-curl-call –

3

貝婁是一個簡單的例子,可以用來實現自定義驗證。在訪問端點的示例中,您必須在POST數據上傳遞用戶名&密碼。

urls.py

urlpatterns = [ 
    url(r'^stuff/', views.MyView.as_view()), 
    ... 
] 

意見。PY

from django.contrib.auth.models import User 
    from rest_framework import viewsets 
    from rest_framework.response import Response 
    from rest_framework.views import APIView  
    from rest_framework.permissions import IsAuthenticated 
    from rest_framework import exceptions 
    from rest_framework import authentication 
    from django.contrib.auth import authenticate, get_user_model 
    from rest_framework.authentication import BasicAuthentication, 
SessionAuthentication 


class ExampleAuthentication(authentication.BaseAuthentication): 

    def authenticate(self, request): 

     # Get the username and password 
     username = request.data.get('username', None) 
     password = request.data.get('password', None) 

     if not username or not password: 
      raise exceptions.AuthenticationFailed(_('No credentials provided.')) 

     credentials = { 
      get_user_model().USERNAME_FIELD: username, 
      'password': password 
     } 

     user = authenticate(**credentials) 

     if user is None: 
      raise exceptions.AuthenticationFailed(_('Invalid username/password.')) 

     if not user.is_active: 
      raise exceptions.AuthenticationFailed(_('User inactive or deleted.')) 


    return (user, None) # authentication successful 


class MyView(APIView): 
    authentication_classes = (SessionAuthentication, ExampleAuthentication,) 
    permission_classes = (IsAuthenticated,) 

    def post(self, request, format=None):  
     content = { 
      'user': unicode(request.user), 
      'auth': unicode(request.auth), # None 
     } 
     return Response(content) 

捲曲

curl -v -X POST http://localhost:8000/stuff/ -d 'username=my_username&password=my_password'