Django CSRFTOKEN 和 android 客户端的问题

Django CSRFTOKEN and problems with android client

我在这里和其他网页上尝试并搜索了很多答案,但我花了一整天还是做不到。

一个朋友构建了一个 django 后端,他让我构建一个 android 应用程序来连接到那个后端,最好的结果是这个 Android Client login to a Django server, how to pass crsf :| 但我无法让它工作,我从服务器获取 CSRF,但随后我尝试使用 URLConnection、HttpClient、HttpPost,还有很多其他示例。

现在我的代码是:

// Create a new HttpClient and Post Header
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://URL-TO-SERVER/");
        String CSRFTOKEN =  getCsrfFromUrl("http://URL-TO-SERVER/");

            // Add your data
            ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("username", mEmail));
            nameValuePairs.add(new BasicNameValuePair("password", mPassword));
            nameValuePairs.add(new BasicNameValuePair("csrfmiddlewaretoken", CSRFTOKEN));
        try {
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            httppost.setHeader("X-CSRFToken", CSRFTOKEN);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        final BasicCookieStore cookieStore =  new BasicCookieStore();
        BasicClientCookie csrf_cookie = new BasicClientCookie("X-CSRFToken", CSRFTOKEN);
        csrf_cookie.setDomain("URL-SERVER");
        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);
        // Execute HTTP Post Request
        HttpResponse response = null;
        try {
            Log.e(TAG,"Token: "+CSRFTOKEN);

            response = httpclient.execute(httppost, localContext);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(response.getAllHeaders());

        try {
            System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (IOException e) {
            e.printStackTrace();
        }

并且 getCsrfFromUrl() 来自 link。而在

nameValuePairs.add(new BasicNameValuePair("csrfmiddlewaretoken", CSRFTOKEN));

我尝试更改 csrftoken 和 X-CSRFToken 的密钥,但我仍然不知道出了什么问题,或者我怎样才能让它工作,也许后端有问题?缺少功能或键? 我尝试做的是登录我需要输入用户名和密码的页面,然后重新收集响应以查看谁输入和使用该数据。

您使用的 getCsrfFromUrl 有问题,它 returns 在响应中找到的第一个 cookie,没有检查它是否是 CSRF cookie,这个应该可以工作:

public String getCsrfFromUrl(String url) {
  HttpGet httpGet = new HttpGet(url);
  HttpResponse httpResponse = httpClientStatic.execute(httpGet);
  HttpEntity httpEntity = httpResponse.getEntity();

  List<Cookie> cookies = httpClientStatic.getCookieStore().getCookies();

  for (Cookie cookie : cookies) {
    if (cookie.getName().equals("csrftoken")) {
      return cookie.getValue();
    }
  }
  return null;  // Or throw exception.
}

然后您可以将返回值用作 POST 参数。

不过,正如您所链接问题的评论中所述,您的 Android 应用访问的视图不需要 CSRF 保护。