[英]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.