2

美好的一天!凌空忽略Cookie标头要求

我的应用程序使用简单的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)); 
    } 
} 

之后,我要求我的设备列表,与当前用户进行联系。在这一刻,我从响应头文件中找到了cookei。完整标题上AUTH请求响应输出:

  • 缓存控制 - 无店内,无缓存,必重新验证,检查后= 0,预检查= 0
  • 连接 - 备存─ alive
  • Content-Length - 16
  • Content-Type - text/html;字符集= UTF-8
  • 日期 - 周五,2015年9月18日6点15分57秒GMT
  • 失效 - 周四,1981年11月19日8点52分00秒GMT
  • 语用 - 无缓存
  • 服务器 - nginx
  • Set-Cookie - PHPSESSID = osurmkq1fmnj462c3hk76l1405;路径=/
  • X-Android的接收-的毫秒时间 - 1442553247146
  • X-Android的发送-的毫秒时间 - 1442553247096
  • X供电-通过 - PHP/27年3月5日

在验证请求onResponce回调我采取设置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; 
    } 
} 

在这里,我把的sessionId到设备列表请求的头信息,但作为回应,我看到这一点:{“地位”:假,“错误”:“没有授权”}

在台式电脑上的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); 
    } 
+0

IMO,不是因为Cookie头,而是getParams(),你应该为POST参数重写getBody()。看看[我的答案在这里](http://stackoverflow.com/questions/32600209/error-sending-data-to-server-using-volley-library/32634261#32634261) – BNK

+0

我没有使用POST请求 –

+0

请尝试http://stackoverflow.com/questions/16626032/volley-post-get-parameters和https://gist.github.com/mstfldmr/f6594b2337e3633673e5 – BNK

回答

4

如果你不需要兼容了Android 2.3 <你只需要添加这行代码在你的活动或应用程序的onCreate。这将激活所有httpURLconnections的默认CookieManager。

CookieHandler.setDefault(new CookieManager()); 

希望得到这个帮助。

如果您需要更多的向后兼容,你需要的cookie管理也为HttpClient的

编辑:在后一种情况下,按照这个答案通过自定义HttpClientStack:https://stackoverflow.com/a/21271347

1

没有与排球头操纵问题我也遇到了。 检查排在Volley内部的HurlStack的源代码。(Volley)中的头部被放入Map中,有时(我仍然不知道为什么),Volley一个接一个地收集同一个键的头部(在你的情况下是Set-Cookie)(首先是这个PHPSESSION,并且那么它会得到你的Set-Cookie的这部分路径)。由于这是一张地图,第一张会被覆盖,而你没有得到你想要的。

我的建议是更改HurlStack的源代码,以便将这些标头放在列表中或使用不同的键(Set-Cookie1,Set-Cookie2,..)。

也看看RetroFit它处理这真的很好。唯一的问题是,使用RetroFit,您不会取消取消请求的可能性。

希望这会有所帮助。