2

我试图在Android中传递一个cookie和一个webview。我尝试使用 CookieManager 和 CookieSyncManager 但无济于事。它不断将我重定向到网站的登录页面。

这是我的代码。

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);        
4

2 回答 2

0

你确认你打电话CookieManager#getCookie(String)后可以打电话把你的 cookie 拿出来CookieManager#setCookie(String, String)吗?

我自己就是这样做的,但我需要添加自定义拦截器DefaultHttpClient以使用 cookieManager 进行 cookie 处理,而不是HttpClient CookieStore.

顺便说一句,CookieManager#setCookie的文档说:

设置的 cookie 必须没有过期,也不能是会话 cookie,否则将被忽略。

但是,在 Android 4.3 模拟器上,我能够使用 android 的CookieManager. 小心在 Android 4.4 上使用它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();
        }
    }

然后,替换DefaultHttpClientcookie 拦截器:

// 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));
于 2014-03-21T14:18:36.000 回答
0

也许您正在创建 CookieManager 的不同实例,因此您无法获取创建它们的实例的 cookie,请尝试创建一个类来管理您的应用程序的 cookie,如下所示:

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

希望这可以帮助!

于 2015-05-27T07:46:24.497 回答