2013-10-20 37 views
2

我試圖在Android中傳遞cookie以及webview。我嘗試使用CookieManager和CookieSyncManager,但無濟於事。它不斷將我重定向到網站的登錄頁面。使用HttpClient和CookieManager將Cookie設置爲WebView

這是我的代碼。

public class RequestSessionState extends AsyncTask<String, Integer, String> { 

    String cookieString; 

    @Override 
    protected String doInBackground(String... params) { 
     // TODO Auto-generated method stub 

     DefaultHttpClient defaultHttpClient = new DefaultHttpClient(); 

     HttpPost postCredentials = new HttpPost("https://www.mywebsite.com/users/login?url=users%2Flogin"); 

     List<NameValuePair> credentialsList = new ArrayList<NameValuePair> (); 
     credentialsList.add(new BasicNameValuePair("data[User][email]", 
       params[0])); 
     credentialsList.add(new BasicNameValuePair("data[User][password]", 
       params[1])); 
     credentialsList.add(new BasicNameValuePair("_method", "POST")); 

     try { 
      postCredentials.setEntity(new UrlEncodedFormEntity(credentialsList)); 
      defaultHttpClient.execute(postCredentials); 

      CookieSyncManager.createInstance(LoginActivity.this); 
      CookieManager cookieManager = CookieManager.getInstance(); 
      cookieManager.setAcceptCookie(true); 
      cookieManager.removeSessionCookie(); 

      SystemClock.sleep(2000); 

      List<Cookie> cookies = defaultHttpClient.getCookieStore().getCookies(); 
      for (Cookie cookie : cookies) { 
       cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain(); 
       cookieManager.setCookie("https://www.mywebsite.com/path", cookieString); 
       System.out.println("COOKIE ----------------- " + cookieString); 
      } 
      CookieSyncManager.getInstance().sync(); 

     } catch (UnsupportedEncodingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ClientProtocolException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return cookieString; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 
     Editor addToSessionState = sessionState.edit(); 
     addToSessionState.putString("cookie", result); 
     addToSessionState.commit(); 

     Intent intent = new Intent(LoginActivity.this, HomeActivity.class); 
     startActivity(intent); 
    } 
} 

而這裏的onCreate在我的下一個活動:

setContentView(R.layout.activity_home); 
    consolePageWebView = new WebView(HomeActivity.this); 
    wvLayout = (RelativeLayout) findViewById(R.id.webViewLayout); 

    LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
    consolePageWebView.setLayoutParams(params); 
    wvLayout.addView(consolePageWebView); 


    sessionState = getSharedPreferences("Session State", Context.MODE_PRIVATE); 
    String cookieString = sessionState.getString("cookie", null); 

    WebSettings webSettings = consolePageWebView.getSettings(); 
    webSettings.setJavaScriptEnabled(true); 
    WebViewClient wvClient = new WebViewClient(); 
    consolePageWebView.setWebViewClient(wvClient); 

    HashMap<String, String> headerMap = new HashMap<String, String>(); 
    headerMap.put("Cookie", cookieString); 
    consolePageWebView.loadUrl("https://www.mywebsite.com/path", headerMap);   

回答

0

你確認,你可以打電話讓你的餅乾了,你叫CookieManager#setCookie(String, String)後?

我只是自己做了這個,但我需要添加自定義攔截器到DefaultHttpClient才能使用cookieManager進行cookie處理,而不是使用HttpClientCookieStore

順便說一句,CookieManager#setCookie的文件說:

該Cookie存在集必須沒有過期,不能是一個會話cookie的 ,否則會被忽略。

但是,在Android 4.3模擬器上,我可以使用android的CookieManager設置和獲取會話cookie。 Beware of using this on Android 4.4 from WebViewClient#shouldInterceptRequest

private static class AndroidRequestAddCookies implements HttpRequestInterceptor { 

     private static final String TAG = "AndroidReqAddCookies"; 

     private final CookieManager cookieManager; 
     private final Handler mainHandler = new Handler(Looper.getMainLooper()); 

     private AndroidRequestAddCookies(CookieManager cookieManager) { 
      this.cookieManager = cookieManager; 
     } 

     public void process(final HttpRequest request, final HttpContext context) 
       throws HttpException, IOException { 
      if (request == null) { 
       throw new IllegalArgumentException("HTTP request may not be null"); 
      } 
      if (context == null) { 
       throw new IllegalArgumentException("HTTP context may not be null"); 
      } 

      // Obtain cookie store 
      CookieStore cookieStore = (CookieStore) context.getAttribute(
        ClientContext.COOKIE_STORE); 
      if (cookieStore == null) { 
       Log.i(TAG, "Cookie store not available in HTTP context"); 
       return; 
      } 

      // Obtain the registry of cookie specs 
      CookieSpecRegistry registry = (CookieSpecRegistry) context.getAttribute(
        ClientContext.COOKIESPEC_REGISTRY); 
      if (registry == null) { 
       Log.i(TAG, "CookieSpec registry not available in HTTP context"); 
       return; 
      } 

      // Obtain the target host (required) 
      HttpHost targetHost = (HttpHost) context.getAttribute(
        ExecutionContext.HTTP_TARGET_HOST); 
      if (targetHost == null) { 
       throw new IllegalStateException("Target host not specified in HTTP context"); 
      } 

      // Obtain the client connection (required) 
      ManagedClientConnection conn = (ManagedClientConnection) context.getAttribute(
        ExecutionContext.HTTP_CONNECTION); 
      if (conn == null) { 
       throw new IllegalStateException("Client connection not specified in HTTP context"); 
      } 

      String policy = HttpClientParams.getCookiePolicy(request.getParams()); 
      if (Log.isLoggable(TAG, Log.DEBUG)) { 
       Log.d(TAG, "CookieSpec selected: " + policy); 
      } 

      URI requestURI; 
      if (request instanceof HttpUriRequest) { 
       requestURI = ((HttpUriRequest) request).getURI(); 
      } else { 
       try { 
        requestURI = new URI(request.getRequestLine().getUri()); 
       } catch (URISyntaxException ex) { 
        throw new ProtocolException("Invalid request URI: " + 
          request.getRequestLine().getUri(), ex); 
       } 
      } 

      String hostName = targetHost.getHostName(); 
      int port = targetHost.getPort(); 
      if (port < 0) { 
       port = conn.getRemotePort(); 
      } 

      CookieOrigin cookieOrigin = new CookieOrigin(
        hostName, 
        port, 
        requestURI.getPath(), 
        conn.isSecure()); 

      final String url = new CookieOriginToUrlConverter().getUrl(cookieOrigin); 

      String cookieHeaderValue = cookieManager.getCookie(url); 
      if (!Strings.isNullOrEmpty(cookieHeaderValue)) { 
       request.addHeader("Cookie", cookieHeaderValue); 
      } 
     } 
    } 

    private static class AndroidResponseProcessCookies implements HttpResponseInterceptor { 

     private static final String TAG = "AndroidRespProcCookies"; 
     private final CookieManager cookieManager; 
     private final Handler mainHandler = new Handler(Looper.getMainLooper()); 

     private AndroidResponseProcessCookies(CookieManager cookieManager) { 
      this.cookieManager = cookieManager; 
     } 

     public void process(final HttpResponse response, final HttpContext context) 
       throws HttpException, IOException { 
      if (response == null) { 
       throw new IllegalArgumentException("HTTP request may not be null"); 
      } 
      if (context == null) { 
       throw new IllegalArgumentException("HTTP context may not be null"); 
      } 

      // Obtain cookie store 
      CookieStore cookieStore = (CookieStore) context.getAttribute(
        ClientContext.COOKIE_STORE); 
      if (cookieStore == null) { 
       Log.i(TAG, "Cookie store not available in HTTP context"); 
       return; 
      } 
      // Obtain actual CookieSpec instance 
      CookieSpec cookieSpec = (CookieSpec) context.getAttribute(
        ClientContext.COOKIE_SPEC); 
      if (cookieSpec == null) { 
       Log.i(TAG, "CookieSpec not available in HTTP context"); 
       return; 
      } 
      // Obtain actual CookieOrigin instance 
      CookieOrigin cookieOrigin = (CookieOrigin) context.getAttribute(
        ClientContext.COOKIE_ORIGIN); 
      if (cookieOrigin == null) { 
       Log.i(TAG, "CookieOrigin not available in HTTP context"); 
       return; 
      } 
      HeaderIterator it = response.headerIterator(SM.SET_COOKIE); 
      processCookies(it, cookieSpec, cookieOrigin, cookieStore); 

      // see if the cookie spec supports cookie versioning. 
      if (cookieSpec.getVersion() > 0) { 
       // process set-cookie2 headers. 
       // Cookie2 will replace equivalent Cookie instances 
       it = response.headerIterator(SM.SET_COOKIE2); 
       processCookies(it, cookieSpec, cookieOrigin, cookieStore); 
      } 
     } 

     private void processCookies(
       final HeaderIterator iterator, 
       final CookieSpec cookieSpec, 
       final CookieOrigin cookieOrigin, 
       final CookieStore cookieStore) { 
      CookieOriginToUrlConverter cookieOriginToUrlConverter = new CookieOriginToUrlConverter(); 
      while (iterator.hasNext()) { 
       final Header header = iterator.nextHeader(); 
       final String cookieUrl = cookieOriginToUrlConverter.getUrl(cookieOrigin); 
       cookieManager.setCookie(cookieUrl, header.getValue()); 
      } 
     } 

     // BEGIN android-added 

     /** 
     * Don't log the cookie's value; that's potentially sensitive information. 
     */ 
     private String cookieToString(Cookie cookie) { 
      return cookie.getClass().getSimpleName() 
        + "[version=" + cookie.getVersion() 
        + ",name=" + cookie.getName() 
        + ",domain=" + cookie.getDomain() 
        + ",path=" + cookie.getPath() 
        + ",expiry=" + cookie.getExpiryDate() 
        + "]"; 
     } 
     // END android-added 
    } 

    private static class CookieOriginToUrlConverter { 
     public String getUrl(CookieOrigin cookieOrigin) { 
      StringBuilder cookieOriginStringBuilder = new StringBuilder(); 
      if (cookieOrigin.isSecure()) { 
       cookieOriginStringBuilder.append("https://"); 
      } else { 
       cookieOriginStringBuilder.append("http://"); 
      } 
      cookieOriginStringBuilder.append(cookieOrigin.getHost()); 
      int port = cookieOrigin.getPort(); 
      if (port > 0) { 
       cookieOriginStringBuilder.append(":"); 
       cookieOriginStringBuilder.append(port); 
      } 
      cookieOriginStringBuilder.append(cookieOrigin.getPath()); 
      return cookieOriginStringBuilder.toString(); 
     } 
    } 

然後,替換DefaultHttpClient的餅乾攔截器:

// remote built-in DefaultHttpClient cookie processing 
defaultHttpClient.removeResponseInterceptorByClass(ResponseProcessCookies.class); 
defaultHttpClient.removeResponseInterceptorByClass(RequestAddCookies.class); 

CookieSyncManager.createInstance(webView.getContext()); 
CookieManager cookieManager = CookieManager.getInstance(); 

// add new cookie processing 
defaultHttpClient.addRequestInterceptor(new AndroidRequestAddCookies(cookieManager)); 
defaultHttpClient.addResponseInterceptor(new AndroidResponseProcessCookies(cookieManager)); 
0

也許你正在創建的CookieManager的不同實例,所以你不能得到你創建它們的實例的餅乾,嘗試創建一個類管理你的應用程序的餅乾這樣的:

import java.net.CookieHandler; 
import java.net.CookieManager; 
import java.net.HttpCookie; 
import java.net.URI; 
import java.net.URISyntaxException; 
import java.util.List; 

public class CookiesGestor { 

    private static CookiesGestor instance; 

    private static CookieManager cookieManager; 

    private CookiesGestor(){ 
     cookieManager = new CookieManager(); 
     CookieHandler.setDefault(cookieManager); 
    } 

    public static CookiesGestor getInstance(){ 
     if(instance==null) { 
      instance = new CookiesGestor(); 
     } 
      return instance; 
    } 

    public void addCookie(String name, String value){ 
     HttpCookie cookie = new HttpCookie(name, value); 
     try { 
      cookieManager.getCookieStore().add(new URI(AppConstant.SERVER_URL), cookie); 
     } catch (URISyntaxException e) { 
      e.printStackTrace(); 
     } 
    } 

    public List getAllCookies(){ 
     return cookieManager.getCookieStore().getCookies(); 
    } 

    public HttpCookie getCookie(String name){ 
     for(HttpCookie cookie:getAllCookies()){ 
      if(cookie.getName().equals(name)){ 
       return cookie; 
      } 
     } 
     return null; 
    } 

} 

您可以就如何在這裏使用的更多信息:http://www.diasoluciones.com/gestion-de-cookies-en-java-y-android

希望這有助於!

相關問題