簡體   English   中英

Django DRF令牌認證

[英]Django DRF Token Authentication

我在DRF基於令牌的身份驗證時遇到問題。 以下是我的目標網頁代碼(登錄后):

@api_view(['GET','POST'],)
def landing(request):
    this_tenant=request.user.tenant
    end=date_first.date.today()
    start=end-date_first.timedelta(days=30)
    sales_daily=sales_day_wise(start, end, this_tenant)
    invoice_value=sales_raised_value(start, end, this_tenant)
    payment_value=sales_collected_value(start, end, this_tenant)
    return render(request,'landing.html', {'sales_daily':json.dumps(sales_daily, cls=DjangoJSONEncoder),\
        'invoice_value':json.dumps(invoice_value, cls=DjangoJSONEncoder), \
        'payment_value':json.dumps(payment_value, cls=DjangoJSONEncoder)})

我使用Django的內置登錄視圖對用戶進行身份驗證和登錄,然后進行了修改以考慮將令牌放入標頭中。 但這也不起作用

這是我的登錄代碼:

#Redirect authenticated users to landing page
def custom_login(request):
    if request.user.is_authenticated():
        token, created = Token.objects.get_or_create(user=request.user)
        request.session['AUTHORIZATION'] = "TOKEN "+token.key
        return redirect(landing)
    else:
        return login(request)

以下是我的DRF設置:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        # 'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}

問題是,當我通過瀏覽器登錄並進入登錄頁面時,DRF無法正常工作,並且出現以下錯誤:

{"detail":"Authentication credentials were not provided."}

原因是請求中不存在自定義DRF標頭(AUTHENTICATION = TOEKN XXXXXXXXXX)。

但是,如果我使用Postman並放入自定義標頭(AUTHENTICATION = TOKEN XXXXXXXXXXXX),則它可以工作。

我該如何解決?

這是否意味着每個視圖都需要自定義標題?

在使用DRF令牌時,是否會打開CSRF漏洞(此問題: Django DRF-如何使用令牌身份驗證進行CSRF驗證 )?

非常感謝!!

  • 我該如何解決? 這是否意味着每個視圖都需要自定義標題? TokenAuthentication用於Single Page App,並且請求標頭中的令牌需要由API客戶端(郵遞員,Javascript或任何其他客戶端)在每個請求上提供。 對於您的情況,如果要使用Django視圖,則應激活SessionAuthentication。 令牌認證和會話認證可以共存。 一種方法是將令牌保存在自定義登錄視圖中的cookie中,並由javascript客戶端讀取。

  • 使用DRF令牌時,是否會打開CSRF漏洞(此問題:Django DRF-如何使用令牌身份驗證進行CSRF驗證)? 是。 但是,有一些方法可以保護請求。 根據DRF文檔“如果在生產中使用令牌身份驗證,則必須確保您的API僅可通過https使用”。 另外,請確保在設置中將ALLOWED_HOSTS設置為您希望Django響應的域,以便服務器不響應其他來源的請求。 除了令牌身份驗證(如上面提到的JWT)之外,還可以使用其他更安全的Auth。

您需要先學習基礎知識。 什么是HTTP,什么是HTTP標頭,什么是Django會話(這不是HTTP標頭,並且該會話的內容不會影響標頭),請閱讀有關令牌認證的Django REST Framework文檔。

如果要在瀏覽器中測試視圖,請在DRF DEFAULT_AUTHENTICATION_CLASSES配置變量中顯式允許Django會話身份驗證。 它可以與令牌認證共存。

除非您使用諸如RESTClient,DHC或REST Easy之類的插件,否則無法使普通的Web瀏覽器將令牌附加到HTTP請求。

您正在將令牌添加到Django會話中,但是您已在DRF中禁用了會話身份驗證,即使您啟用了該身份驗證,DRF也不會從Django會話中讀取令牌,因為API客戶端無法將令牌添加到Django會話中。 即使DRF會從Django會話中讀取令牌,這也完全沒有意義,因為客戶端無法控制會話的內容。 會話變量是在服務器上設置的,而不是在客戶端上設置的。

REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.IsAuthenticated',
        ],
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.BasicAuthentication',  # enables simple command line authentication
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.TokenAuthentication',
        )
    }

大多數情況下,添加'rest_framework.authentication.SessionAuthentication'可以解決此問題。

另類

您可以使用:

'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
   ),

但是現在,為了訪問受保護的api網址,您必須包含Authorization:JWT標頭。

如果它適用於curl或郵遞員,則表明后端不是問題。 客戶端代碼當然是一個問題。 您是否看過對REST api的請求? 我建議並確保令牌在標頭中傳遞並正確設置格式。

暫無
暫無

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

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