簡體   English   中英

Django Rest 框架令牌認證

[英]Django Rest Framework Token Authentication

我已經閱讀了 Django Rest Framework Guides 並完成了所有教程。 一切似乎都有意義,並且按應有的方式工作。 我得到了基本和會話身份驗證的工作描述。

django rest 框架 - api 指南

但是,我在文檔的令牌身份驗證部分苦苦掙扎,它有點缺乏或沒有像教程那樣深入。

django-rest-framework - 令牌認證

它說我需要為用戶創建令牌,但確實說明了 models.py 的位置?

有人可以為初學者更好地解釋文檔的令牌身份驗證部分嗎?

@ian-clelland 已經提供了正確答案。 他的帖子中沒有提到一些小片段,所以我將記錄完整的過程(我使用的是 Django 1.8.5 和 DRF 3.2.4):

  1. 在創建超級用戶之前,請執行以下操作。 否則,超級用戶不會創建他/她的令牌。

  2. 轉到settings.py並添加以下內容:

     INSTALLED_APPS = ( 'rest_framework', 'rest_framework.authtoken', 'myapp', ) REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', ) }
  3. myappmodels.py中添加以下代碼:

     from django.db.models.signals import post_save from django.dispatch import receiver from rest_framework.authtoken.models import Token from django.conf import settings # This code is triggered whenever a new user has been created and saved to the database @receiver(post_save, sender=settings.AUTH_USER_MODEL) def create_auth_token(sender, instance=None, created=False, **kwargs): if created: Token.objects.create(user=instance)

    或者,如果您想更明確一點,請在myapp項目下創建一個名為signals.py的文件。 將上面的代碼放入其中,然后在__init__.py中,寫入import signals

  4. 打開一個控制台窗口,導航到您的項目目錄,然后輸入以下命令:

     python manage.py migrate python manage.py makemigrations

    看看你的數據庫,應該創建一個名為authtoken_token的表,其中包含以下字段:key(這是令牌值)、created(創建日期時間)、user_id(引用 auth_user 表的 id 列的外鍵)

  5. 使用python manage.py createsuperuser創建一個超級用戶。 現在,使用select * from authtoken_token;查看數據庫中的authtoken_token表; ,您應該會看到已添加一個新條目。

  6. 使用curl或更簡單的替代httpie來測試對您的 api 的訪問,我使用的是 httpie:

     http GET 127.0.0.1:8000/whatever 'Authorization: Token your_token_value'

    而已。 從現在開始,對於任何 API 訪問,您需要在 HTTP 標頭中包含以下值(注意空格):

     Authorization: Token your_token_value
  7. (可選)如果您提供用戶名和密碼,DRF 還提供返回用戶令牌的功能。 您所要做的就是在urls.py中包含以下內容:

     from rest_framework.authtoken import views urlpatterns = [ ... url(r'^api-token-auth/', views.obtain_auth_token), ]

    使用httpie驗證:

     http POST 127.0.0.1:8000/api-token-auth/ username='admin' password='whatever'

    在返回正文中,您應該看到:

     { "token": "blah_blah_blah" }

而已!

不,不在你的 models.py 中——在模型方面,你需要做的就是在你的INSTALLED_APPS中包含適當的應用程序( rest_framework.authtoken )。 這將提供一個外鍵給用戶的 Token 模型。

您需要做的是決定何時以及如何創建這些令牌對象。 在您的應用程序中,是否每個用戶都會自動獲得令牌? 還是只有某些授權用戶? 還是只有當他們特別要求時?

如果每個用戶都應該有一個令牌,那么在您鏈接到的頁面上會有一段代碼向您展示如何設置一個信號來自動創建它們:

@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

(把放在models.py文件的任何地方,它會在Django線程啟動時注冊)

如果只應在特定時間創建令牌,那么在您的視圖代碼中,您需要在適當的時間創建並保存令牌:

# View Pseudocode
from rest_framework.authtoken.models import Token

def token_request(request):
    if user_requested_token() and token_request_is_warranted():
        new_token = Token.objects.create(user=request.user)

創建(並保存)令牌后,它將可用於身份驗證。

在 Django 1.8.2 和 rest framework 3.3.2 上,以上所有內容不足以啟用基於令牌的身份驗證。

雖然 REST_FRAMEWORK 設置在 django 設置文件中指定,但基於函數的視圖需要 @api_view 裝飾器:

from rest_framework.decorators import api_view

@api_view(['POST','GET'])
def my_view(request):
    if request.user.is_authenticated():
       ...

否則根本不執行令牌認證

只是為了增加我的兩分錢,如果您有一個處理用戶創建(和激活)的自定義用戶管理器,您也可以像這樣執行此任務:

from rest_framework.authtoken.models import Token
# Other imports

class UserManager(BaseUserManager):

    def create_user(self, **kwargs):
        """
        This is your custom method for creating user instances. 
        IMHO, if you're going to do this, you might as well use a signal.

        """
        # user = self.model(**kwargs) ...
        Token.objects.create(user=user)

    #You may also choose to handle this upon user activation. 
    #Again, a signal works as well here.

    def activate_user(**kwargs):
        # user = ...
        Token.objects.create(user=user)

如果您已經創建了用戶,那么您可以下拉到終端中的 python shell 並為您的數據庫中的所有用戶創建令牌。

>>> from django.contrib.auth.models import User
>>> from rest_framework.authtoken.models import Token 
>>> for user in User.objects.all():
>>> ...    Token.objects.create(user=user)

希望有幫助。

有一種更簡潔的方式來獲取用戶令牌。

只需運行 manage.py shell

接着

from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
u = User.objects.get(username='admin')
token = Token.objects.create(user=u)
print token.key

那么應該在表 DB_Schema.authtoken_token 中找到一條記錄

除了這里的優秀答案,我想提一個更好的令牌認證方法:JSON Web Token Authentication。 http://getblimp.github.io/django-rest-framework-jwt/提供的實現非常容易使用。

此答案中更詳細地解釋了這些好處。

JSON Web Token Authentication 是比 Token Authentication 更好的選擇。 該項目已使用 Django ( http://getblimp.github.io/django-rest-framework-jwt/ ) 實現了 JWT Auth,但目前該項目未維護。

對於替代方案,您可以遵循: https ://github.com/davesque/django-rest-framework-simplejwt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM