2012-02-12 42 views
10

Tôi muốn ứng dụng Android của tôi có thể gửi một số thông tin đến máy chủ django của tôi. Vì vậy, tôi đã làm cho các ứng dụng Android gửi một yêu cầu bài đến trang mysite/tải lên và xem django cho trang này sẽ làm việc dựa trên dữ liệu bài. Vấn đề là phản hồi mà máy chủ cung cấp cho yêu cầu đăng khiếu nại về xác minh csrf không thành công. Nhìn vào vấn đề có vẻ như tôi có thể có để có được một mã thông báo csrf từ máy chủ đầu tiên sau đó làm bài với mã thông báo Nhưng tôi không chắc chắn làm thế nào tôi làm điều này. Chỉnh sửa: Tôi đã phát hiện ra rằng tôi có thể loại bỏ xác minh crsf cho chế độ xem này bằng cách sử dụng trình xem trang @csrf_exempt nhưng tôi không chắc chắn đây có phải là giải pháp tốt nhất hay không. mã Android của tôi:Android gửi yêu cầu gửi đến máy chủ django csrf không

// Create a new HttpClient and Post Header 
        HttpClient httpclient = new DefaultHttpClient(); 
        HttpPost httppost = new HttpPost(URL); 

        // Add your data 
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
        nameValuePairs.add(new BasicNameValuePair("scoreone", scoreone)); 
        nameValuePairs.add(new BasicNameValuePair("scoretwo", scoretwo)); 
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
        System.out.println("huzahhhhhhh"); 
        // Execute HTTP Post Request 
        HttpResponse response = httpclient.execute(httppost); 
        BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
        StringBuffer sb = new StringBuffer(""); 
        String line = ""; 
        String NL = System.getProperty("line.separator"); 
        while ((line = in.readLine()) != null) { 
         sb.append(line + NL); 
        } 
        in.close(); 
        String result = sb.toString(); 
        System.out.println("Result: "+result); 

và mã quan điểm của tôi để xử lý việc tải lên:

# uploads a players match 
def upload(request): 
    if request.method == 'POST': 
     scoreone = int(request.POST['scoreone']) 
     scoretwo = int(request.POST['scoretwo']) 
     m = Match.objects.create() 
     MatchParticipant.objects.create(player = Player.objects.get(pk=1), match = m, score = scoreone) 
     MatchParticipant.objects.create(player = Player.objects.get(pk=2), match = m, score = scoretwo) 
    return HttpResponse("Match uploaded") 

enter code here 
+0

tôi nhận được 403 lỗi, tôi đang làm điều tương tự . Bạn có thể giúp tôi, nếu bạn đã giải quyết được lỗi. –

Trả lời

2

Viết trang trí riêng và thêm một số "bí mật" tiêu đề để yêu cầu của bạn. https://code.djangoproject.com/browser/django/trunk/django/views/decorators/csrf.py

def csrf_exempt(view_func): 
     """ 
     Marks a view function as being exempt from the CSRF view protection. 
     """ 
     # We could just do view_func.csrf_exempt = True, but decorators 
     # are nicer if they don't have side-effects, so we return a new 
     # function. 
     def wrapped_view(request,*args, **kwargs): 
      return view_func(request, *args, **kwargs) 
      if request.META.has_key('HTTP_X_SKIP_CSRF'): 
       wrapped_view.csrf_exempt = True 
     return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) 
+3

Bạn đang bỏ qua bảo mật tại đây. – remus

+1

@remus CSRF cho ứng dụng Android không có ý nghĩa. Giả mạo yêu cầu trang web chéo là dành cho các trang web cổ điển. Điều vô nghĩa của nó đối với API. – iddqd

2

Tắt xác minh CSRF chắc chắn hoạt động! nhưng bạn có chắc chắn muốn làm điều đó không? dòng suy nghĩ ban đầu của bạn; nhận mã thông báo từ máy chủ và gửi cùng với dữ liệu POST tốt hơn nhiều.

Mã thông báo csrf thường có trong biểu mẫu cookie. Ví dụ với khung công tác Django bạn có cookie có tên là csrftoken, bạn cần lấy giá trị đó và đăng lên máy chủ dưới dạng 'X-CSRFToken'

10

Trước tiên, bạn cần đọc mã thông báo csrf từ cookie từ yêu cầu xem trước :

httpClient.execute(new HttpGet(uri)); 
CookieStore cookieStore = httpClient.getCookieStore(); 
List <Cookie> cookies = cookieStore.getCookies(); 
for (Cookie cookie: cookies) { 
    if (cookie.getDomain().equals(Constants.CSRF_COOKIE_DOMAIN) && cookie.getName().equals("csrftoken")) { 
     CSRFTOKEN = cookie.getValue(); 
    } 
} 

Nếu nhìn của bạn không được render một mẫu chứa csrf_token mẫu thẻ, Django có thể không được thiết lập cookie CSRF token. Đây là phổ biến trong trường hợp biểu mẫu được thêm động vào trang. Để giải quyết trường hợp này, Django cung cấp trình xem trang trí bắt buộc cài đặt của cookie: Ensure_csrf_cookie(). - https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

Sau đó, bạn có thể vượt qua nó đến máy chủ trên các tiêu đề bài yêu cầu và cookie khi làm bài theo yêu cầu:

httpPost.setHeader("Referer", Constants.SITE_URL); 
httpPost.setHeader("X-CSRFToken", CSRFTOKEN); 

DefaultHttpClient client = new DefaultHttpClient(); 
final BasicCookieStore cookieStore = new BasicCookieStore(); 

BasicClientCookie csrf_cookie = new BasicClientCookie("csrftoken", CSRFTOKEN); 
csrf_cookie.setDomain(Constants.CSRF_COOKIE_DOMAIN); 
cookieStore.addCookie(csrf_cookie); 

// Create local HTTP context - to store cookies 
HttpContext localContext = new BasicHttpContext(); 
// Bind custom cookie store to the local context 
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); 

HttpResponse response = client.execute(httpPost, localContext); 
+0

Tôi đang làm điều tương tự, nhưng tôi nhận được lỗi 403. Tôi đã thử gửi cookie, tiêu đề. Nhưng tôi vẫn gặp lỗi tương tự. –

+0

Điều này làm việc rực rỡ cho tôi, cảm ơn! –

Các vấn đề liên quan