【问题标题】:Why do I receive CSRF Token mismatch error in Android Studio even when GET and POST tokens are the same?为什么即使 GET 和 POST 令牌相同,我也会在 Android Studio 中收到 CSRF 令牌不匹配错误?
【发布时间】:2016-08-25 09:59:24
【问题描述】:

我正在为我朋友的网站 (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;
}

在我的登录类中,我在执行 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

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

【问题讨论】:

    标签: android node.js mongodb express csrf


    【解决方案1】:

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

    【讨论】:

    • 您好,感谢您的回复,不幸的是,更新到 v2.1.1 后问题仍然存在。
    • 糟糕!那么代码中的任何地方都可能存在一些问题!不确定抱歉!
    猜你喜欢
    • 1970-01-01
    • 2016-02-13
    • 2017-09-01
    • 2020-07-21
    • 2022-01-11
    • 1970-01-01
    • 2018-02-20
    • 2022-08-19
    • 1970-01-01
    相关资源
    最近更新 更多