2014-01-23 47 views
11

我有幾個我想用cURL測試的API。我試圖做一個GET如下:如何捲曲經過驗證的Django應用程序?

curl --user username:password --request GET http://my_domain/get_result/52d6428f3ea9a008358ad2d8/ 

在服務器上,它顯示'302'(這意味着重定向,對吧?)。我猜它重定向到「登錄/」頁面。

完成這件事的正確方法是什麼?

編輯:我嘗試:

curl -c cookies.txt -b cookies.txt -L -d @login_form.txt http://my_domain/login/ 

其中login_form.txt含 「的用戶名的用戶名= &密碼=密碼& this_is_the_login_form = 1」。不起作用。沒有生成cookies.txt文件。並沒有登錄發生。你能告訴我你如何使用cURL實現登錄到Django嗎?

回答

30

這是一個完全編碼的答案。該解決方案的思路是:

  1. ,你必須先用GET來獲得所產生的餅乾文件訪問登錄頁面,
  2. 然後解析CSRF令牌出了餅乾的文件
  3. 並做登錄使用POST請求,將數據傳遞給-d

然後可以隨時執行任何請求,利用在數據($DJANGO_TOKEN)或用一個自定義首部X-CSRFToken CSRF令牌。要註銷,只需刪除Cookie文件。

請注意,您需要引用者(-e)才能使Django的CSRF檢查很高興。

LOGIN_URL=https://yourdjangowebsite.com/login/ 
YOUR_USER='username' 
YOUR_PASS='password' 
COOKIES=cookies.txt 
CURL_BIN="curl -s -c $COOKIES -b $COOKIES -e $LOGIN_URL" 

echo -n "Django Auth: get csrftoken ..." 
$CURL_BIN $LOGIN_URL > /dev/null 
DJANGO_TOKEN="csrfmiddlewaretoken=$(grep csrftoken $COOKIES | sed 's/^.*csrftoken\s*//')" 

echo -n " perform login ..." 
$CURL_BIN \ 
    -d "$DJANGO_TOKEN&username=$YOUR_USER&password=$YOUR_PASS" \ 
    -X POST $LOGIN_URL 

echo -n " do something while logged in ..." 
$CURL_BIN \ 
    -d "$DJANGO_TOKEN&..." \ 
    -X POST https://yourdjangowebsite.com/whatever/ 

echo " logout" 
rm $COOKIES 

我有這樣的代碼,它使用提交POST數據文件的一個稍微更安全的版本,因爲在GitHub上一個要點是:django-csrftoken-login-demo.bash

有趣的背景閱讀Django的CSRF令牌上docs.djangoproject.com

+0

我不得不說這節省了我的一天。雖然它現在工作正常,但現在沒有引用者.. – darxsys

+2

「sed's /^.* csrftoken \ s * //'」在csrf值之前放置了額外的空間。這就是爲什麼,我用「awk {'print $ 7'}」代替。 – VolkanT

+0

在macOS上,我在令牌前面添加了一個額外的選項卡 - 所以我用'[[:space:]]'替換了'\ s',如[超級用戶發佈]中所推薦的(https://superuser.com /問題/ 112834 /如何配搭空白,在-SID#)。另外,我不得不修改登錄URL,因爲我得到了302s。 – whlteXbread

2

在curl請求中傳遞用戶名:密碼僅適用於HTTP身份驗證,這不是現在大多數網站如何進行身份驗證的方式。相反,您必須發佈到登錄頁面,獲取cookie,然後在請求所需頁面時將其傳回。

+0

我在我的問題中添加了一個編輯。請看看。 –

2

其實@Paterino答案是正確的,但它不會在每個sed實現上都有效。相反sed 's/^.*csrftoken\s*//')我們可以使用sed 's/^.*csrftoken[[:blank:]]*//')這是更老式。 MacOSXs捲曲不使用轉義,所以\n\t\s根本不起作用。

+0

一旦你有足夠的[聲譽](http://stackoverflow.com/help/whats-reputation),你將能夠[評論](http:// stackoverflow。com/help/privileges/comment)。另外檢查這[我可以做什麼,而不是](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-c​​an-i-do-instead )。 – thewaywewere

+1

感謝您指出這一點。答案是關於一般方法,實現細節是指GNU版本的sed(從Linux開始),僅僅是一個例子。我有一個要點使GNU sed在Mac上也是默認的:https://gist.github.com/bittner/5436f3dc011d43ab7551 – Peterino

+0

不錯,看起來像完美的解決方案,我會稍後再嘗試。我的帖子或多或少是對你的回答以及其他可能像我一樣掙扎的人的延伸。 – jinni