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,您不會取消取消請求的可能性。

希望這會有所幫助。