I would like my android app to be able to send some information to my django server. So I made the android app send a post request to the mysite/upload page and django's view for this page would do work based on the post data. The problem is the response the server gives for the post request complains about csrf verication failed. Looking in to the problem it seems I might have to get a csrf token from the server first then do the post with that token But I am unsure how I do this. Edit: I have found out that I can knock off the crsf verification for this view using a view decorator @csrf_exempt but I am not sure if this is the best solution. My android code:
// 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);
and my views code for handling the upload:
# 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
First you need to read the csrf token from the cookies from a preview request:
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();
}
}
If your view is not rendering a template containing the csrf_token template tag, Django might not set the CSRF token cookie. This is common in cases where forms are dynamically added to the page. To address this case, Django provides a view decorator which forces setting of the cookie: ensure_csrf_cookie(). -- https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
Then you can pass it to the server on the post request headers and cookies when doing the post request:
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);
Write own decorator and add some "secret" header to your request. 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With