У меня есть сервер, который отправляет моему приложению Android файл cookie сеанса, который будет использоваться для аутентифицированной связи. Я пытаюсь загрузить WebView с URL-адресом, указывающим на тот же сервер, и пытаюсь передать файл cookie сеанса для аутентификации. Я замечаю, что он работает с перебоями, но не знаю почему. Я использую один и тот же файл cookie сеанса для выполнения других вызовов на моем сервере, и они никогда не завершают проверку подлинности. Я наблюдаю эту проблему только при попытке загрузить URL-адрес в WebView, и это происходит не каждый раз. Очень неприятно.
Ниже приведен код, который я использую для этого. Любая помощь будет оценена.
String myUrl = ""http://mydomain.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);
Ответы:
Спасибо, justingrammens ! Это сработало для меня, мне удалось поделиться файлом cookie в моих запросах DefaultHttpClient и активности WebView:
//------- 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(); }
источник
Спасибо Android за испорченное воскресенье. . . Вот что исправило мои приложения (после того, как вы запустите свой веб-просмотр)
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptThirdPartyCookies( webView, true ); }
Я должен сказать, что приведенные выше ответы, вероятно, сработают, но в моей ситуации, когда Android перешел на версию 5 +, мои приложения javascript для android webview умерли.
источник
Решение: 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");
источник
cookie
?, я получаю только:PHPSESSID=ljfakdjfklasdfaj
!, этого достаточно?решение - дать Android достаточно времени для обработки файлов cookie. Вы можете найти дополнительную информацию здесь: http://code.walletapp.net/post/46414301269/passing-cookie-to-webview
источник
Я бы сохранил этот файл cookie сеанса в качестве предпочтения и принудительно повторно заселил им диспетчер файлов cookie. Похоже, что cookie сеанса не переживает перезапуск активности
источник
Я потратил большую половину из трех часов, работая над очень похожей проблемой. В моем случае у меня было несколько вызовов, которые я сделал веб-сервису, используя
DefaulHttpClient
а затем я хотел установить сеанс и все другие соответствующие файлы cookie в моемWebView
.Я не знаю, решит ли это вашу проблему, поскольку я не знаю, что
getCookie()
делает ваш метод, но в моем случае мне действительно пришлось позвонить.cookieManager.removeSessionCookie();
Сначала удалите файл cookie сеанса, а затем снова добавьте его. Я обнаружил, что когда я пытался установить
JSESSIONID
файл cookie, не удаляя его предварительно, значение, которое я хотел установить, не сохранялось. Не уверен, что это поможет вам в конкретной проблеме, но подумал, что поделюсь тем, что нашел.источник
CookieManager.getInstance().removeAllCookie ();
?После некоторого времени исследований я собрал несколько фрагментов, которые помогли мне прийти к этому решению. После того, как CookieSyncManager устарел, это может быть лучшим способом установить конкретный файл cookie для веб-просмотра в Kotlin в настоящее время, вам больше ничего не понадобится.
private fun setCookie(){ val webView = WebView(this) // this = context val cookieManager = CookieManager.getInstance() cookieManager.acceptCookie() val domain = "https://www.yourdomain.com/" webView.webViewClient = WebViewClient() webView.settings.javaScriptEnabled = true cookieManager.setCookie(domain,"$cookieKey=$cookieValue") cookieManager.setAcceptThirdPartyCookies(webView, true) webView.loadUrl(domain) }
источник
У меня здесь другой подход, чем у других людей, и это подход, который гарантированно работает без использования CookieSyncManager (где вы находитесь во власти семантики типа «Обратите внимание, что даже sync () происходит асинхронно»).
По сути, мы переходим к правильному домену, а затем выполняем javascript из контекста страницы, чтобы установить файлы cookie для этого домена (так же, как и сама страница). У этого метода есть два недостатка: это может привести к дополнительному времени прохождения туда и обратно из-за дополнительного 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, если вы не будете осторожны.
источник
Это рабочий фрагмент кода.
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 - это объект DefaultHttpClient, который вы использовали в запросе HttpGet / HttpPost. Также нужно убедиться, что имя и значение файла cookie должны быть указаны
String cookieString = cookie.getName() + "=" + cookie.getValue();
setCookie установит cookie для данного URL.
источник
Я волшебным образом решил все свои проблемы с файлами cookie с помощью этой строки в onCreate:
CookieHandler.setDefault(new CookieManager());
изменить: сегодня он перестал работать. :( какая хрень, android.
источник
С этим тоже столкнулся. Вот что я сделал.
В моем LoginActivity внутри моей AsyncTask у меня есть следующее:
// ГДЕ CookieStoreHelper.sessionCookie - это еще один класс, содержащий переменную sessionCookie, определенную как List cookies; и 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 }
Совет: установите firebug в firefox или используйте консоль разработчика в Chrome и сначала протестируйте свою веб-страницу, запишите файл cookie и проверьте домен, чтобы вы могли его где-нибудь сохранить, и убедитесь, что вы правильно устанавливаете правильный домен.
Изменить: отредактировал CookieStoreHelper.cookies на CookieStoreHelper.sessionCookie
источник
Мой рабочий код
public View onCreateView(...){ mWebView = (WebView) view.findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); ... ... ... CookieSyncManager.createInstance(mWebView.getContext()); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); //cookieManager.removeSessionCookie(); // remove cookieManager.removeAllCookie(); //remove // Recommended "hack" with a delay between the removal and the installation of "Cookies" SystemClock.sleep(1000); cookieManager.setCookie("https://my.app.site.com/", "cookiename=" + value + "; path=/registration" + "; secure"); // ; CookieSyncManager.getInstance().sync(); mWebView.loadUrl(sp.getString("url", "") + end_url); return view; }
Для отладки запроса cookieManager.setCookie (....); Я рекомендую вам просмотреть содержимое базы данных webviewCookiesChromium.db (хранится в "/data/data/my.app.webview/database") Там вы можете увидеть правильные настройки.
Отключение cookieManager.removeSessionCookie (); и / или cookieManager.removeAllCookie ();
//cookieManager.removeSessionCookie(); // and/or //cookieManager.removeAllCookie();"
Сравните установленное значение с тем, что установлено браузером. Отрегулируйте запрос на установку файлов 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" // These flags I found in the database: + "; path=/registration" + "; domain=my.app.site.com"
источник
Пара комментариев (по крайней мере, для API> = 21), которые я узнал из своего опыта и вызвал у меня головную боль:
http
иhttps
URL-адреса разные. Установка cookie дляhttp://www.example.com
отличается от установки cookie дляhttps://www.example.com
https://www.example.com/
работает, ноhttps://www.example.com
не работает.CookieManager.getInstance().setCookie
выполняет асинхронную операцию. Таким образом, если вы загрузите URL-адрес сразу после его установки, не гарантируется, что файлы cookie уже будут записаны. Чтобы предотвратить неожиданное и нестабильное поведение, используйте CookieManager # setCookie (String url, String value, ValueCallback callback) ( ссылка ) и начните загружать URL после того, как будет вызван обратный вызов.Я надеюсь, что мои два цента сэкономят время некоторым людям, чтобы вам не пришлось столкнуться с теми же проблемами, что и мне.
источник
Я столкнулся с такой же проблемой, и это решит эту проблему во всех версиях 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); } }
источник
Обратите внимание, что может быть лучше использовать поддомены вместо обычного URL. Итак, установите
.example.com
вместоhttps://example.com/
.Благодаря Джоди Джейкобусу Гирсу и другим я написал так:
if (savedInstanceState == null) { val cookieManager = CookieManager.getInstance() cookieManager.acceptCookie() val domain = ".example.com" if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.setCookie(domain, "token=$token") { view.webView.loadUrl(url) } cookieManager.setAcceptThirdPartyCookies(view.webView, true) } else { cookieManager.setCookie(domain, "token=$token") view.webView.loadUrl(url) } } else { // Check whether we're recreating a previously destroyed instance. view.webView.restoreState(savedInstanceState) }
источник
Не используйте свой необработанный URL
Вместо того:
cookieManager.setCookie(myUrl, cookieString);
используйте это так:
cookieManager.setCookie("your url host", cookieString);
источник