为什么即使GET和POST令牌相同,我也会在Android Studio中收到CSRF令牌不匹配错误?

时间:2016-04-30 07:07:32

标签: android node.js mongodb express csrf

我正在为我的朋友的网站(node.js / mongoDB)开发一个Android应用程序(android studio),我正在通过应用程序进行用户登录。服务器端的一切正常,但在尝试登录android时,服务器收到POST 403错误,CSRF令牌不匹配异常。在android studio中我使用的是HttpUrlConnection,在我的主RequestServer类中,我创建了一个GET方法,它将请求作为字符串获取并将CSRF标记作为子字符串返回:

public String getCsrf(String url) {
    try {
        urlObj = new URL(url);

        conn = (HttpURLConnection) urlObj.openConnection();

        conn.setDoOutput(false);

        conn.setRequestMethod("GET");

        conn.setUseCaches(false);

        conn.setConnectTimeout(15000);

        conn.connect();

            //Receive the response from the server
        InputStream in = new BufferedInputStream(conn.getInputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
        result = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            result.append(line);
        }
        reader.close();
        jsonstr = result.toString();

        Log.d("getCsrf JSON", "result: " + jsonstr);

        // getting csrf token
        int position = result.indexOf("<meta name=\"csrf-token\" content");
        // position of token in GET response
        String token = result.substring(position + 33, position + 30 + 41);
        System.out.println("Printing CSRF content from string in getCsrf....... " + token);

        return token;

    } catch (IOException e) {
        e.printStackTrace();
    }
    conn.disconnect();
    return null;
}

在我的Login类中,我在执行POST请求时添加了此标记以及我的电子邮件/密码参数:

@Override
        public void onClick(View v) {                
            email = email_txt.getText().toString();
            pwd = pw_txt.getText().toString();
            RequestServer sR = new RequestServer();
            //calling 'getCsrfFromUrl' method from RequestServer class to retrieve token (Async background method)
            String CSRFToken = sR.getCsrfFromUrl("http://192.168.2.6:3000/login"); // Async background method for getCsrf
            System.out.println("token in Login.java: " + CSRFToken);
            HashMap<String, String> params = new HashMap<>();
            params.put("_csrf", CSRFToken); // the token being added to the parameters HashMap matches with the one I am retrieving from my GET request
            params.put("email", email);
            params.put("password", pwd);
            JSONObject json = sR.postJSON("http://192.168.2.6:3000/login", params);// Async background method for makeHttpRequest.....rest of code not shown as error occurs at this postJSON line
    }

现在,我的RequestServer类中的方法是我的POST请求:

public JSONObject makeHttpRequest(String url,
                                  HashMap<String, String> params) {

    sbParams = new StringBuilder();
    int i = 0;
    for (String key : params.keySet()) {
        // append params on POST 
        if (i != 0){
            sbParams.append("&");
        }
        sbParams.append(key).append("=").append(params.get(key));

        i++;
    }
        // request method is POST
        try {
            urlObj = new URL(url);

            conn = (HttpURLConnection) urlObj.openConnection();

            conn.setDoOutput(true); // set to true so that we can POST data to the url

            conn.setRequestMethod("POST"); // default is GET

            conn.setRequestProperty("Accept", "application/json");

            conn.setUseCaches(false);

            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);

            conn.connect();

            paramsString = sbParams.toString();

            wr = new DataOutputStream(conn.getOutputStream()); // Transmit data by writing to the stream returned by this
            wr.writeBytes(paramsString);
            wr.flush(); // clean up
            wr.close();
            System.out.println("POST Response Status: " + conn.getResponseCode() + " " + conn.getResponseMessage());

        } catch (IOException e) {
            e.printStackTrace();
        }

    try {
        //Receive the response from the server
        InputStream in = new BufferedInputStream(conn.getInputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
        result = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            result.append(line);
        }

        reader.close();
        jsonstr = result.toString();

        Log.d("POST JSON", "result: " + jsonstr);

    } catch (IOException e) {
        e.printStackTrace();
    }
    conn.disconnect();

    // try to parse the string to a JSON object
    try {
        jObj = new JSONObject(jsonstr);
    } catch (JSONException e) {
        Log.e("POST JSON Parser", "Error parsing data " + e.toString() + " " + jObj);
    }

    // return JSON Object
    return jObj;

}

这是我在android studio中的错误控制台(注意两个令牌在打印语句中是相同的,但我仍然收到CSRF令牌不匹配错误): android stack trace

从服务器端返回错误: node POST 403 error

我环顾了几个星期,对于这种特殊情况没有任何帮助。只是想知道我还缺少什么?提前谢谢!

1 个答案:

答案 0 :(得分:0)

请将您的Android Studio更新为v2.1.1 它有一个修复。它应该工作!