【发布时间】:2015-09-20 17:16:13
【问题描述】:
我正在使用 django 服务器在 android 中学习网络。我能够发出 GET 请求并获得 json 响应以及我能够获得 csrf cookie,但是当我使用 cookie 并发出 post 请求时,django 给出 403 表示 csrf 验证失败。
我正在使用 csrf 令牌设置所需的标头“X-CSRFToken”,并且还传递了 cookie (cookieString),但到目前为止还没有成功。
这是我在 android 中的课程。我可以使用 python-requests 库发出发布请求,因此 django 服务器没有问题,这个 android 代码中有一些问题。请提出任何解决此问题的方法。
private void signupUser() {
validateData();
new PostData().execute();
}
private void validateData() {
try {
urlParameters= URLEncoder.encode("code","utf-8")+"="+URLEncoder.encode("100","utf-8");
urlParameters+= "&"+URLEncoder.encode("username","utf-8")+"="+URLEncoder.encode(username,"utf-8");
urlParameters+= "&"+URLEncoder.encode("password","utf-8")+"="+URLEncoder.encode(password,"utf-8");
urlParameters+= "&"+URLEncoder.encode("firstName","utf-8")+"="+URLEncoder.encode(firstName,"utf-8");
urlParameters+= "&"+URLEncoder.encode("lastName","utf-8")+"="+URLEncoder.encode(lastName,"utf-8");
urlParameters+= "&"+URLEncoder.encode("email","utf-8")+"="+URLEncoder.encode(email,"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private class PostData extends AsyncTask<Void,Void,String> {
@Override
protected String doInBackground(Void... params) {
String response="";
try {
// Manage Cookies
String cookieString="";
String csrftoken="";
cookieManager=io.getCookiesFromURLConnection(urlConnection);
List<HttpCookie> cookies=cookieManager.getCookieStore().getCookies();
Iterator<HttpCookie> cookieIterator=cookies.iterator();
while(cookieIterator.hasNext()){
HttpCookie cookie=cookieIterator.next();
cookieString+=cookie.getName()+"="+cookie.getValue()+";";
if(cookie.getName().equals("csrftoken")){
csrftoken=cookie.getValue();
}
}
url= new URL(Utils.USER_SIGNUP_URL);
urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("User-Agent", Utils.USER_AGENT);
urlConnection.setRequestProperty("Connection", Utils.KEEP_ALIVE);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestProperty("X-CSRFToken", csrftoken);
urlConnection.setRequestProperty("Cookies", cookieString);
OutputStreamWriter streamWriter=new OutputStreamWriter(urlConnection.getOutputStream());
streamWriter.write(urlParameters);
streamWriter.flush();
streamWriter.close();
int responseCode=urlConnection.getResponseCode();
response=io.readStream(urlConnection);
} catch (FileNotFoundException ex){
ex.printStackTrace();
try {
response=io.readErrorStream(urlConnection);
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
private class GetData extends AsyncTask<Void,Void,String> {
@Override
protected String doInBackground(Void... params) {
if(checkConnection()){
try {
return fetchData();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}else{
Toast.makeText(SignUpActivity.this, "Please connect to internet", Toast.LENGTH_LONG).show();
}
return "";
}
@Override
protected void onPostExecute(String s) {
if(s==null){
return ;
}
super.onPostExecute(s);
signupButton.setEnabled(true);
}
}
private boolean checkConnection() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
String result = "";
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
public String fetchData() throws IOException {
String result="";
try {
url= new URL(Utils.USER_SIGNUP_URL);
urlConnection=(HttpURLConnection)url.openConnection();
result=io.readStream(urlConnection);
cookieManager=io.getCookiesFromURLConnection(urlConnection);
} catch (MalformedURLException e) {
e.printStackTrace();
}
return result;
}
}
这里是 io 类: 公共类 io {
public static CookieManager getCookiesFromURLConnection(HttpURLConnection urlConnection){
Map<String,List<String >> headers= urlConnection.getHeaderFields();
CookieManager cookieManager=new CookieManager();
List<String> cookiesHeader=headers.get("Set-Cookie");
if(cookiesHeader!=null){
for(String cookie: cookiesHeader){
cookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0));
}
}
return cookieManager;
}
}
Android Logcat:
09-19 20:55:37.479 17085-17734/kam.app.learnnetworking W/System.err﹕ java.io.FileNotFoundException: http://<website-ip-address>/api/user-login/
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:206)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at kam.app.learnnetworking.networking.io.readStream(io.java:28)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at kam.app.learnnetworking.activities.SignUpActivity$PostData.doInBackground(SignUpActivity.java:172)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at kam.app.learnnetworking.activities.SignUpActivity$PostData.doInBackground(SignUpActivity.java:123)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:292)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
09-19 20:55:37.484 17085-17734/kam.app.learnnetworking W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
有什么方法可以获取发送的请求并在 android 日志中打印?我是 android 网络新手,所以不太了解。
【问题讨论】:
-
请修剪您的问题以仅包含相关代码,而不是仅仅转储整个项目,更有可能让人们以这种方式阅读它!
-
我已经编辑了这个问题,但没有必要为此投反对票。
-
logcat 中的第一个错误行:09-19 20:55:37.479 17085-17734/kam.app.learnnetworking W/System.err: java.io.FileNotFoundException: http://
/api/user-login/ -
即检查HttpUrlconnection var的值
-
@Fred 谢谢,但它为响应 403 提供了 filenotfound。当我使用 readErrorStream 时,它为我提供了 csrf 失败响应的 html。
标签: android python django cookies