ANDROID : Share session between Webview and httpcl

2019-01-13 05:23发布

问题:

I have actually a logged session in my WebView. But I use also httpclient to send and get data from the web. I saw on the internet that it's impossible to get the content of a WebView, so I needed to use my httpclient to get data from a webservice.

The problem is that this webservice uses sessions... and my session is in my WebView, so the httpclient doesn't have it and I can't access the content of the webservice.

I see many posts about this problem but I didn't understand the solution.

Here is what i did on my onPageStarted :

CookieManager mgr = CookieManager.getInstance();
Log.i( "URL", url );
Log.i("Cookie",mgr.getCookie("mywebsite.com"));
String cookie_string = mgr.getCookie("mywebsite.com");
if(cookie_string.length() > 1) {                    
    Data.instance().getPref().edit().putString("cookie",cookie_string).commit();
}

I saw that I have this kind of things, so I hope those include session too: (i remove the number)

__utma=......(number)......; 

__utmc=number;

__utmz=number.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); 

wt3_eid=%number%number; 

wt3_sid=%number

Then i don't know what to do in order to set this cookie in my httpclient. I try that, with no success :

HttpClient client = new DefaultHttpClient();
BasicCookieStore cookieStore = new BasicCookieStore();
String login_cookie_string = Data.instance().getPref().getString("cookie", "");
String[] cookie_parts = null;
if(login_cookie_string.length()> 0)
{

    //debug_view.setText(login_cookie_string);
    Log.d("COOKIE", login_cookie_string);
    cookie_parts = login_cookie_string.split(";");

    for(int t=0;t < cookie_parts.length;t++)
    {
        String[] cookieContent = cookie_parts[t].split("=");
        Cookie login_cookie = new BasicClientCookie(cookieContent[0],cookieContent[1]);
        ((BasicClientCookie) login_cookie).setDomain("mywebsite.com");
        cookieStore.addCookie(login_cookie);
    }

}
((AbstractHttpClient) client).setCookieStore(cookieStore);

回答1:

So , this is what I did and it worked for me -

HttpRequestBase request = new HttpGet(uri);
request.addHeader("Cookie", getCookieFromAppCookieManager(uri.toString()));

Now the implmentation for the getCookieFromAppCookieManager is as follows -
The method gets the cookies for a given URL from the application CookieManager. The application CookieManager manages the cookies used by an application's WebView instances.

@param url the URL for which the cookies are requested
@return value the cookies as a string, using the format of the 'Cookie' HTTP request header
@throws MalformedURLException


public static String getCookieFromAppCookieManager(String url) throws MalformedURLException {
    CookieManager cookieManager = CookieManager.getInstance();
    if (cookieManager == null)
        return null;
    String rawCookieHeader = null;
    URL parsedURL = new URL(url);

    // Extract Set-Cookie header value from Android app CookieManager for this URL
    rawCookieHeader = cookieManager.getCookie(parsedURL.getHost());
    if (rawCookieHeader == null)
        return null;
    return rawCookieHeader;
}


回答2:

Follow this tuto :

http://metatroid.com/article/Android:%20handling%20web%20service%20authentication

=============================== Here the content of the webpage =====

Something you might find yourself doing in Android is web authentication. Most web sites issue a cookie to track session ID's and keep a user logged in. In order to maintain this authentication, you will need to keep cookies synced between activities and between http clients and webviews.

The method I ended up doing, which seems to work well enough, was to create a class that extends Application, then define a single HttpClient to be used throughout the rest of the Application. That code looks like:

public class AppSettings extends Application {
    private static final DefaultHttpClient client = createClient();

    @Override
    public void onCreate(){
    }

    static DefaultHttpClient getClient(){
            return client;
    }
    private static DefaultHttpClient createClient(){
            BasicHttpParams params = new BasicHttpParams();
            SchemeRegistry schemeRegistry = new SchemeRegistry();
            schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
            schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
            ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
            DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);
            httpclient.getCookieStore().getCookies();
            return httpclient;
    }

This class also creates an HttpClient that is suitable for AsyncTasks and making multiple simultaneous http requests. Using ThreadSafeClientConnManager for the ClientConnectionManager let's you run http requests inside AsyncTasks without causing a force close when you press the back button and start a second, or third.

It also creates a single default cookie store that can be accessed in all your activities. You would use this in your other activities by calling the getClient() method.

For example

public class SomeActivity extends Activity {
        static DefaultHttpClient mClient = AppSettings.getClient();
        ...
        try {

            HttpGet httpget = new HttpGet('URL');
            HttpResponse response;
            response = mClient.execute(httpget);
            ...
        }
        ...
    }

If you find it necessary to use a webview and need it to access and use the same cookies as your client. You can sync the client's cookie store using CookieManager: (in onPageStarted method)

DefaultHttpClient mClient = AppSettings.getClient();


Cookie sessionInfo;
List<Cookie> cookies = mClient.getCookieStore().getCookies();

if (! cookies.isEmpty()){
        CookieSyncManager.createInstance(getApplicationContext());
        CookieManager cookieManager = CookieManager.getInstance();

        for(Cookie cookie : cookies){
                sessionInfo = cookie;
                String cookieString = sessionInfo.getName() + "=" + sessionInfo.getValue() + "; domain=" + sessionInfo.getDomain();
                cookieManager.setCookie("example.com", cookieString);
                CookieSyncManager.getInstance().sync();
        }
}

You will need to switch example.com with the correct domain.