Volley忽略Cookie标头请求

Евг*_*цов 2 android androidhttpclient android-volley android-cookiemanager

美好的一天!

我的应用程序使用简单的http客户端 - 服务器通信,在客户端与Volley库建立.首先,我启动一个授权请求:

public class AuthenticationRequest extends StringRequest {

    private static final String TAG = AuthenticationRequest.class.getSimpleName();

    private String login;
    private String password;

    public AuthenticationRequest(int method,
                                 String url,
                                 Response.Listener<String> listener,
                                 Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    protected Map<String, String> getParams() {
        HashMap<String, String> parameters = new HashMap<>();
        parameters.put("login", login);
        parameters.put("password", password);
        return parameters;
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        for (Map.Entry<String, String> entry : response.headers.entrySet()) {
            Log.d(TAG, entry.getKey() + " -- " + entry.getValue());
        }

        String sessionId = response.headers.get("Set-Cookie");
        return Response.success(sessionId, HttpHeaderParser.parseCacheHeaders(response));
    }
}
Run Code Online (Sandbox Code Playgroud)

在那之后,我请求我的设备列表,与当前用户有关.此刻,我有一个来自响应标题的cookei.auth请求上的完整标头响应输出:

  • 缓存控制 - 无存储,无缓存,必须重新验证,后检查= 0,预检查= 0
  • 连接 - 保持活力
  • 内容长度 - 16
  • Content-Type - text/html; 字符集= utf-8的
  • 日期 - 星期五,2015年9月18日06:15:57 GMT
  • Expires - Thu,1981年11月19日08:52:00 GMT
  • Pragma - no-cache
  • 服务器 - nginx
  • Set-Cookie - PHPSESSID = osurmkq1fmnj462c3hk76l1405; 路径= /
  • X-Android-Received-Millis - 1442553247146
  • X-Android-Sent-Millis - 1442553247096
  • X-Powered-By - PHP/5.3.27

在onResponce回调Auth请求我将Set-Cookie值作为sessionId并启动DeviceListRequest:

public class DeviceListRequest extends StringRequest {

    private static final String TAG = DeviceListRequest.class.getSimpleName();

    private String phpSessId;

    public DeviceListRequest(int method,
                             String url,
                             Response.Listener<String> listener,
                             Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }

    public void setPhpSessId(String phpSessId) {
        this.phpSessId = phpSessId;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        HashMap<String, String> headers = new HashMap<>();
        Log.d(TAG, phpSessId);
        headers.put("Cookie", phpSessId);
        return headers;
    }
}
Run Code Online (Sandbox Code Playgroud)

这里我把sessionId放到设备列表请求的标题中,但作为回应我看到:{"status":false,"error":"No authorization"}

在桌面PC上的Chrome浏览器中接收到的设备列表 - 问题出在Android上.

拜托,你能告诉我,我的代码有什么问题吗?也许我在设置标题时错了???

发送请求程序代码:

public void authenticationRequest(String login, String password) {
        final AuthenticationRequest request = new AuthenticationRequest(Request.Method.GET,
                AUTHENTICATION_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Log.d(TAG, "Response: " + response);
                        phpSessId = response;
                        deviceListRequest(phpSessId);
                    }
                },
                this);

        request.setLogin(login);
        request.setPassword(password);

        requestQueue.add(request);
    }

    public void deviceListRequest(String phpSessId) {
        DeviceListRequest request = new DeviceListRequest(Request.Method.GET,
                DEVICE_LIST_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Log.d(TAG, "Response: " + response);
                    }
                },
                this);

        request.setPhpSessId(phpSessId);

        requestQueue.add(request);
    }
Run Code Online (Sandbox Code Playgroud)

gba*_*tta 5

如果您不需要与Android <2.3兼容,则只需在活动或应用程序的onCreate中添加此行代码.这将激活所有httpURLconnections的默认cookieManager.

CookieHandler.setDefault(new CookieManager());
Run Code Online (Sandbox Code Playgroud)

希望这有帮助.

如果您需要更多向后兼容性,则还需要针对HttpClient进行Cookie管理

编辑:在后一种情况下按照此答案传递自定义HttpClientStack:https://stackoverflow.com/a/21271347