96

認証された通信に使用されるセッション Cookie を Android アプリに送信するサーバーがあります。同じサーバーを指す URL を使用して WebView をロードしようとしていますが、認証のためにセッション Cookie を渡そうとしています。断続的に動作することを観察していますが、その理由はわかりません。同じセッション Cookie を使用して、サーバーで他の呼び出しを行いますが、認証に失敗することはありません。この問題は、WebView に URL を読み込もうとしたときにのみ観察され、毎回発生するわけではありません。とてもイライラします。

以下は、これを行うために使用しているコードです。どんな助けでも大歓迎です。

String myUrl = "http://example.com/"; 
CookieSyncManager.createInstance(this); 
CookieManager cookieManager = CookieManager.getInstance(); 
Cookie sessionCookie =  getCookie(); 
if(sessionCookie != null){ 
    String cookieString = sessionCookie.getName() +"="+sessionCookie.getValue()+"; domain="+sessionCookie.getDomain(); 
    cookieManager.setCookie(myUrl, cookieString); 
    CookieSyncManager.getInstance().sync(); 
} 

WebView webView = (WebView) findViewById(R.id.webview); 
webView.getSettings().setBuiltInZoomControls(true); 
webView.getSettings().setJavaScriptEnabled(true); 
webView.setWebViewClient(new MyWebViewClient()); 
webView.loadUrl(myUrl);
4

16 に答える 16

57

ありがとうございます!それは私にとってはうまくいきました.DefaultHttpClientリクエストとWebViewアクティビティ内でCookieを共有することができました:

//------- Native request activity
private DefaultHttpClient httpClient;
public static Cookie cookie = null;

//After Login
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
    cookie = cookies.get(i);
}

//------- Web Browser activity
Cookie sessionCookie = myapp.cookie;
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
if (sessionCookie != null) {
    cookieManager.removeSessionCookie();
    String cookieString = sessionCookie.getName() + "=" + sessionCookie.getValue() + "; domain=" + sessionCookie.getDomain();
    cookieManager.setCookie(myapp.domain, cookieString);
    CookieSyncManager.getInstance().sync();
}   
于 2010-02-27T23:13:31.440 に答える
14

ソリューション:Webview CookieSyncManager

CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(mWebView.getContext());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeSessionCookie();
cookieManager.setCookie("http://xx.example.com","mid="+MySession.GetSession().sessionId+" ; Domain=.example.com");
cookieSyncManager.sync();

String cookie = cookieManager.getCookie("http://xx.example.com");

Log.d(LOGTAG, "cookie ------>"+cookie);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new TuWebViewClient());
mWebView.loadUrl("http://xx.example.com");
于 2012-06-27T20:32:53.703 に答える
6

解決策は、Android が Cookie を処理するのに十分な時間を与えることです。詳細については、http: //code.walletapp.net/post/46414301269/passing-cookie-to-webviewをご覧ください。

于 2011-04-18T13:09:12.053 に答える
3

私は 3 時間の半分以上を非常によく似た問題に取り組んできました。私の場合、 を使用して Web サービスに対して行った多数の呼び出しがありDefaulHttpClient、セッションと他のすべての対応する Cookie を に設定したいと考えていましたWebView

メソッドが何をするかわからないので、これで問題が解決するかどうかはわかりませんgetCookie()が、私の場合は実際に呼び出す必要がありました。

cookieManager.removeSessionCookie();

最初にセッション Cookie を削除してから、再度追加します。最初に Cookie を削除せずに Cookie を設定しようとすると、JSESSIONID設定したい値が保存されていないことがわかりました。これが特定の問題に役立つかどうかはわかりませんが、私が見つけたものを共有したいと思いました.

于 2010-01-23T03:13:03.793 に答える
3

I would save that session cookie as a preference and forcefully repopulate the cookie manager with it. It sounds that session cookie in not surviving Activity restart

于 2009-10-31T00:03:46.023 に答える
1

onCreate の次の 1 行で、すべての Cookie の問題を魔法のように解決しました。

CookieHandler.setDefault(new CookieManager());

編集:今日は機能しなくなりました。:(なんてこった、アンドロイド。

于 2013-10-18T19:18:50.397 に答える
1

私はここで他の人々とは異なるアプローチをとっています.CookieSyncManagerを扱わなくても動作することが保証されているアプローチです.

基本的に、正しいドメインを参照し、ページ コンテキストから JavaScript を実行して、そのドメインの Cookie を設定します (ページ自体と同じ方法)。この方法の 2 つの欠点は、追加の http 要求を作成する必要があるため、余分な往復時間が発生する可能性があることです。また、サイトに空白のページに相当するものがない場合は、最初にロードした URL がフラッシュされてから、正しい場所に移動する可能性があります。

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.cookie.Cookie;
import android.annotation.SuppressLint;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class WebViewFragment {
    private static final String BLANK_PAGE = "/blank.html"

    private CookieSyncManager mSyncManager;
    private CookieManager mCookieManager;

    private String mTargetUrl;
    private boolean mInitializedCookies;
    private List<Cookie> mAllCookies;

    public WebViewFragment(Context ctx) {
        // We are still required to create an instance of Cookie/SyncManager.
        mSyncManager = CookieSyncManager.createInstance(ctx);
        mCookieManager = CookieManager.getInstance();
    }

    @SuppressLint("SetJavaScriptEnabled") public void loadWebView(
                String url, List<Cookie> cookies, String domain) {
        final WebView webView = ...

        webView.setWebViewClient(new CookeWebViewClient());
        webView.getSettings().setJavaScriptEnabled(true);

        mInitializedCookies = false;
        mTargetUrl = url;
        mAllCookies = cookies;
        // This is where the hack starts.
        // Instead of loading the url, we load a blank page.
        webView.loadUrl("http://" + domain + BLANK_PAGE);
    }

    public static String buildCookieString(final Cookie cookie) {
        // You may want to add the secure flag for https:
        // + "; secure"
        // In case you wish to convert session cookies to have an expiration:
        // + "; expires=Thu, 01-Jan-2037 00:00:10 GMT"
        // Note that you cannot set the HttpOnly flag as we are using
        // javascript to set the cookies.
        return cookie.getName() + "=" + cookie.getValue()
                    + "; path=" + cookie.getPath()
                    + "; domain=" + cookie.getDomain()
    };

    public synchronized String generateCookieJavascript() {
        StringBuilder javascriptCode = new StringBuilder();
        javascriptCode.append("javascript:(function(){");
        for (final Cookie cookie : mAllCookies) {
            String cookieString = buildCookieString(cookie);
            javascriptCode.append("document.cookie=\"");
            javascriptCode.append(
                     StringEscapeUtils.escapeJavascriptString(cookieString));
            javascriptCode.append("\";");
        }
        // We use javascript to load the next url because we do not
        // receive an onPageFinished event when this code finishes.
        javascriptCode.append("document.location=\"");
        javascriptCode.append(
                StringEscapeUtils.escapeJavascriptString(mTargetUrl));
        javascriptCode.append("\";})();");
        return javascriptCode.toString();
    }

    private class CookieWebViewClient extends WebViewClient {
        @Override public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (!mInitializedCookies) {
                mInitializedCookies = true;
                // Run our javascript code now that the temp page is loaded.
                view.loadUrl(generateCookieJavascript());
                return;
            }
        }
    }
}

Cookie の送信元のドメインを信頼できる場合は、apache commons なしで済む可能性がありますが、注意しないと XSS のリスクが発生する可能性があることを理解する必要があります。

于 2013-04-02T19:02:44.390 に答える
1

これも遭遇。これが私がしたことです。

LoginActivity の AsyncTask 内には、次のものがあります。

CookieStoreHelper.cookieStore = new BasicCookieStore();
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, CookieStoreHelper.cookieStore);

HttpResponse postResponse = client.execute(httpPost,localContext);
CookieStoreHelper.sessionCookie = CookieStoreHelper.cookieStore.getCookies();

//WHERE CookieStoreHelper.sessionCookie は、List cookies として定義された変数 sessionCookie を含む別のクラスです。および cookieStore は BasicCookieStore cookieStore として定義されます。

次に、私の WebView が配置されているフラグメントには、次のものがあります。

//DECLARE LIST OF COOKIE
List<Cookie> sessionCookie;

メソッド内または WebViewClient() を設定する直前

WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);

sessionCookie = CookieStoreHelper.cookieStore.getCookies();
CookieSyncManager.createInstance(webView.getContext());
CookieSyncManager.getInstance().startSync();
CookieManager cookieManager = CookieManager.getInstance();
CookieManager.getInstance().setAcceptCookie(true);
if (sessionCookie != null) {
   for(Cookie c:  sessionCookie){
      cookieManager.setCookie(CookieStoreHelper.DOMAIN, c.getName() + "=" + c.getValue());
   }
   CookieSyncManager.getInstance().sync();

 }

 webView.setWebViewClient(new WebViewClient() {
    //AND SO ON, YOUR CODE
 }

簡単なヒント: Firefox に firebug をインストールするか、Chrome で開発者コンソールを使用して、最初に Web ページをテストし、Cookie をキャプチャしてドメインをチェックし、どこかに保存して、正しいドメインを正しく設定していることを確認します。

編集: CookieStoreHelper.cookies を CookieStoreHelper.sessionCookie に編集

于 2014-11-07T07:57:20.543 に答える
1

これは実用的なコードです。

    private void setCookie(DefaultHttpClient httpClient, String url) {
    List<Cookie> cookies = httpClient.getCookieStore().getCookies();
    if (cookies != null) {
        CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);

        for (int i = 0; i < cookies.size(); i++) {
            Cookie cookie = cookies.get(i);
            String cookieString = cookie.getName() + "=" + cookie.getValue();
            cookieManager.setCookie(url, cookieString);
        }
        CookieSyncManager.getInstance().sync();
    }
}

ここで、httpclient は、HttpGet/HttpPost 要求で使用した DefaultHttpClient オブジェクトです。また、確認する必要があるのは、Cookie の名前と値です。指定する必要があります。

String cookieString = cookie.getName() + "=" + cookie.getValue();

setCookie は、指定された URL の Cookie を設定します。

于 2013-08-06T10:30:10.107 に答える
0

私は同じ問題に直面しており、すべてのAndroidバージョンでこの問題を解決します

private void setCookie() {
    try {
        CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            cookieManager.setCookie(Constant.BASE_URL, getCookie(), value -> {
                String cookie = cookieManager.getCookie(Constant.BASE_URL);
                CookieManager.getInstance().flush();
                CustomLog.d("cookie", "cookie ------>" + cookie);
                setupWebView();
            });
        } else {
            cookieManager.setCookie(webUrl, getCookie());
            new Handler().postDelayed(this::setupWebView, 700);
            CookieSyncManager.getInstance().sync();
        }

    } catch (Exception e) {
        CustomLog.e(e);
    }
}
于 2018-10-29T08:36:33.583 に答える
-4

生の URL を使用しないでください

それ以外の:

cookieManager.setCookie(myUrl, cookieString); 

次のように使用します。

cookieManager.setCookie("your url host", cookieString); 
于 2015-05-12T04:54:01.307 に答える