2016-04-01 13 views
3

Test için Django siteme giriş yapmak için requests kullanıyorum (ve evet, Django TestClient hakkında biliyorum, ancak burada düz http'a ihtiyacım var). Giriş yapabilirim ve istekleri aldığım sürece her şey yolunda.django ve python istekleri - 403 gönderi istek üzerine alma

ileti yerine'u kullanmaya çalıştığımda, csrf katman yazılımından 403 elde ediyorum. Şimdilik bunun üzerinde çalıştığım bir @crsf_exempt kullanarak çalıştım, ancak daha uzun vadeli bir çözüm tercih ediyorum.

with requests.Session() as ses: 

    try: 

     data = { 
      'username': self.username, 
      'password': self.password, 
     } 

     ses.get(login_url) 
     try: 
      csrftoken = ses.cookies["csrftoken"] 
     except Exception, e: 
      raise 
     data.update(csrfmiddlewaretoken=csrftoken) 

     _login_response = ses.post(login_url, data=data) 

     logger.info("ses.cookies:%s" % (ses.cookies)) 

     assert 200 <= _login_response.status_code < 300, "_login_response.status_code:%s" % (_login_response.status_code) 

     response = ses.post(
      full_url, 
      data=data, 
      ) 

     return self._process_response(response) 

giriş çalışıyor ve ben belirteci burada CSRF görebilirsiniz:

Bu benim kodudur. Ancak, ara yazılım kurabiyeleri boş olarak görmektedir. Bununla birlikte, ara katman çerezleri boş olarak görmektedir.

def process_view(self, request, callback, callback_args, callback_kwargs): 

    if getattr(request, 'csrf_processing_done', False): 
     return None 

    try: 
     csrf_token = _sanitize_token(
      request.COOKIES[settings.CSRF_COOKIE_NAME]) 
     # Use same token next time 
     request.META['CSRF_COOKIE'] = csrf_token 
    except KeyError: 
     # import pdb 
     # pdb.set_trace() 
     import logging 
     logger = logging.getLogger(__name__) 
     logger.info("request.COOKIES:%s" % (request.COOKIES)) 

ben isteğin session.post çağrı yolu ile bir şey eksik:

INFO:django.middleware.csrf:request.COOKIES:{} 

ben buna günlüğü kodunu ekledikten? Çerez eklemeyi denedim, farketmedim. Ancak, crsf ara katman yazılımının neden hata yaptığını anlayabiliyorum. Çerezlerin oturumun bir parçası olduğunu sanıyordum, o yüzden neden ikinci yazımda kayıplar?

  response = ses.post(
       self.res.full_url, 
       data=data, 
       cookies=ses.cookies, 
       ) 

How to send cookies in a post request with the Python Requests library? esinlenerek Bu varyasyon, aynı zamanda şey csrf katman geçirilen yol açmamıştır: müteakip istekler için

  response = ses.post(
       self.res.full_url, 
       data=data, 
       cookies=dict(csrftoken=csrftoken), 
       ) 

cevap

4

girişten sonra, yerine başlığında X-CSRFToken olarak temin deneyin.

benim için çalıştı aşağıdaki

:

with requests.Session() as sesssion: 
    response = session.get(login_url) 
    response.raise_for_status() # raises HTTPError if: 400 <= status_code < 600 

    csrf = session.cookies['csrftoken'] 
    data = { 
     'username': self.username, 
     'password': self.password, 
     'csrfmiddlewaretoken': csrf 
    } 


    response = session.post(login_url, data=data) 
    response.raise_for_status() 

    headers = {'X-CSRFToken': csrf, 'Referer': url} 
    response = session.post('another_url', data={}, headers=headers) 
    response.raise_for_status() 

    return response # At this point we probably made it 

Dokümanlar referans: Ayrıca yerine csrf_exempt arasında, görünümü üzerinde this decorator kullanmayı deneyebilirsiniz https://docs.djangoproject.com/en/dev/ref/csrf/#csrf-ajax

+0

Yardımlarınız için teşekkürler. Tamam çalışıyor, bazı değişiklikler yapmak zorunda kaldım, bunu anlamak uzun zaman aldı, çünkü csrf jetonu ** session.post (login_url, data = data) 'dan sonra değişiyor. Ve bu değişmiş token 'X-CSRFToken' içine girmesi gereken şey. Ama oldukça iyi görünüyor ve X-CSRFToken JS Ajax mesajları için yaptığım ile eşleşiyor. Yapacağım şey, haftanın sonunda cevabımı - temizlik koduyla - yazmak ve bana doğru yönde işaret ettiğin cevabını kabul etmektir. Şimdilik açık tutulması, çünkü bu ucuz bir ödül değildi ve bir başkası daha büyük bir cevaba sahip olabilir. Kendine iyi bak. –

+0

Pazartesi günü kabul etmediysem, bir vızıltı ver. Ödemeyi sürdürebilirsem, bu yüzden 100 puan kazanacağımı, ama eğer böyle bir durumda olmamanın lütfunu kaçırmak istemediğini * kabul ediyorum. –

+0

Ödül hakkında endişelenme! Bu soruya cevap verdim çünkü bir süre önce çözdüm. Oturum açmak için gönderdikten sonra csrf belirteci haklısınız, ancak oturumlar kullanıyorsanız, sizin için şeffaf bir şekilde işleniyor. Tam bir çözüm için kütüphanemde github'u (erişim kontrollerini kontrol eder) tam olarak yaptığınız şekilde kontrol edebilirsiniz: https: // github.com/stphivos/fnval/blob/master/fnval/net.py # L41 – fips

1

. Sorununuzu çoğaltmaya çalıştım ve bu benim için de işe yaradı.

from django.views.decorators.csrf import ensure_csrf_cookie` 

@ensure_csrf_cookie 
def your_login_view(request): 
    # your view code 
+0

'warranty_csrf_cookie' işi, sayfada form bulunmasa bile bir csrf belirtecinin sönmesini sağlamaktır. Bu problemim yok - yazdığım özellikle csrf_token'i görebildiğimi söylüyor, sadece gerçek hedefe (giriş değil) POST'a nasıl geri döneceğini bilmiyorum. –

+0

Tamam, yorumunuz için teşekkürler, burada en önemli şey sizin için çalışan bir çözüm bulmanız;), ve buna ulaşmak için yardım etmek isteyenler, bunu aklımda tutmamız ve benim amacım buydu;) . Tekrar teşekkürler ve iyi şanslar! –