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 保护。
我在这里和其他网页上尝试并搜索了很多答案,但我花了一整天还是做不到。
一个朋友构建了一个 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 保护。