How to cURL an Authenticated Django App?

后端 未结 4 1337
囚心锁ツ
囚心锁ツ 2020-12-01 05:40

I\'ve a few APIs I\'d like to test with cURL. I tried doing a GET as follows:

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


        
相关标签:
4条回答
  • 2020-12-01 06:08

    Actually @Paterino answer is correct but it will not work on every implementation of sed. Instead sed 's/^.*csrftoken\s*//') we can use sed 's/^.*csrftoken[[:blank:]]*//') which is more old fashioned. MacOSXs curl doesn't use escaping, so \n\t\s don't work at all.

    0 讨论(0)
  • 2020-12-01 06:09

    Passing username:password in a curl request is only good for HTTP Authentication, which isn't how most websites do auth these days. Instead, you'll have to post to the login page, get the cookie, then pass it back when requesting your desired page.

    0 讨论(0)
  • 2020-12-01 06:12

    Here is a fully coded answer. The idea of the solution is:

    1. you have to first visit the login page with GET to get the cookies file generated,
    2. then parse the CSRF token out of the cookies file
    3. and do the login using a POST request, passing the data with -d.

    Afterwards you can perform any request always using that CSRF token in the data ($DJANGO_TOKEN) or with a custom X-CSRFToken header. To log out simply delete the cookies file.

    Note that you need a referer (-e) to make Django's CSRF checks happy.

    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
    

    I have a slightly more secure version of this code, which uses a file for submitting the POST data, as a Gist on GitHub: django-csrftoken-login-demo.bash

    Interesting background reading on Django's CSRF token is on docs.djangoproject.com.

    0 讨论(0)
  • 2020-12-01 06:20

    To use the token with a get request, use

    $CURL_BIN \
        -H "$DJANGO_TOKEN" \
        -X GET https://yourdjangowebsite.com/whatever/
    

    I tried using -d with -X GET, however it resulted in weird socket behaviour on the server side (Heruko H18 errors).

    0 讨论(0)
提交回复
热议问题