When installing a fresh build of my application and attempting to log in, it fails because the authentication cookie sent by the server is never stored. Closing the application and re-launching fixes the issue. There is an identical issue for cordova-plugin-wkwebview-engine here. Is this one of the issues that has been / will be fixed in this fork, or is there a viable workaround at this time?
I have the same issue, cookies not working the first time.
Same issue here. I don't think there is a solution in this fork. This is really a blocker for us in user experience. Please take a look at this!
This also causes websockets to break on many apps that rely on sticky session cookies to connect to the same server. Even if you were to use localstorage for auth, it's hard to get around the sticky session issue.
This fork seems to have fix for this issue: https://github.com/agarcia17/cordova-plugin-wkwebview-engine
It is behind the current master of the plugin though.
Yikes, that is one heavy handed fix.
@mukana-lahtelat I don't think this fixes XHR requests, it seems to only deal with the loadRequest lifecycle, meaning on raw page loads it will re-inject the cookies. The better fix for non-XHR requests is outlined here.
I also seem to be experiencing this issue, but for me the cookies don't ever seem to be sent or stored even when I restart the application (using a simulator). I can see Set-Cookie is being sent back properly, and this all works fine in UIWebView, but for WKWebView the cookies never seem to be stored at all.
+1.
Because of the cookie issue, I had to uninstall the WKWebView plugin.
Any solutions?
+1
Still having this issue! Went back to UIWebView
+1
Is it something what is going to be fixed in this plugin pretty soon?
I uninstall WKWebView plugin then reinstall ios platform, so it working now.
This appears to be causing problems for me as well
When you will call first the same request using cordova-plugin-fetch, it will "unlock" saving set-cookie header in next normal request. That fixes issue when app is opened first time after installation. But it's not so elegant solution ;) ...
I'm using in my app cordova-plugin-file-transfer to download/save files on device. In request there is no cookie header, even when app is not first opened on device. Looks like above solution with cordova-plugin-fetch solves that issue .. Maybe it will help someone to better investigate and solve that issue.
+1
mindf**k
edit:
@mezykr your solution worked, thanks.
I also found this https://github.com/psirenny/cordova-plugin-wkwebview-sync-cookies that I believe does the same thing under the hood.
What happened to the PR ? Did it work? Why was it not merged?
Has anyone found a fix for this issue that is not listed here? Is anyone from Ionic working on this at all?
+1 Would also love to see a working fix!
+1 Please fix this issue.
I've made a workaround for this so that the cookies work again after the first startup of the app. For that I created this plugin based on a different persons advice. If i find the Person again ill give him credit here and in the plugin of course:
https://github.com/COMLINE-AG/native-xhr-plugin/
This will make the use of cookies possible again.
So do a native request and wait 3 seconds? Really?
@oliverjanik Well there is no real alternative for this until Ionic fixed this issue. I've tried many workarounds, but this workaround was the only one that worked.
If u have concerns about the 3 seconds of waiting, then make a request on application startup. If the user has to enter login data then the 3 seconds have passed already and the user will notice nothing about it.
Edit: I forgot to mention that u need to do this native request once. After this request and the wait of 3 seconds u can use normal xhr again.
I tried most of the wkwebview xhr workarounds and went with this one:
https://github.com/sortdinc/cordova-plugin-wkwebview-ionic-xhr
The plugin caches cookies at the native layer between requests but it does not attempt to sync cookies between the WKWebView and the native sessions. From the JavaScript context, this means "document.cookie" won't contain any cookies returned from XHR handled at the native layer and the native iOS XHR will not see any cookies returned from remote resources fetched by the browser context, such as images.
@asrytis do you use that to do all you ajax calls then?
Are there any news on this?
I think you need to get Apple to fix their Webview, to solve this, cleanly.
Any updates on this?
Can confirm otherwise that https://github.com/sortdinc/cordova-plugin-wkwebview-ionic-xhr suggested by @asrytis seems to do the trick in the meantime!
I can also confirm that the fork mentioned by @asrytis works with cookies on first app startup. However, there are issues playing media files, it seems there are still several major issues with the WK Webview that are not resolved https://issues.apache.org/jira/browse/CB-10141?jql=project%20%3D%20CB%20AND%20status%20%3D%20Open%20AND%20labels%20%3D%20wkwebview-known-issues
I have the same problem here. Cookies do not work the first time. If I kill and reopen the application, it works ...
This is still a large issue, anything we can do about it? With XHR requests, we use bearer auth that we set up manually, but for requests made by the browser, like through img tags, there's literally no workaround for this. Authenticated images just don't load the first time users use our app and there's nothing we can do about it.
EDIT from the future: For those looking to implement the solution @asrytis mentions below, you should use XMLHttpRequest's responseType = "blob"; feature to download the image and URL.createObjectUrl to save the data.
More info at this incredibly useful blog post and on MDN
We use xhr to load images that need session cookies. Fortunately we only have a few of those so not a big problem in our app.
If anyone is interested in some backgrounds of this problem you may find this answer on SO very interesting: https://stackoverflow.com/a/49534854/2757879
With this in mind I could make it to work by injecting a dummy cookie (foo=bar) for my domain right before the webview was initialized. After this has been done once the mentioned syncing works reliable ever after.
While it's not easy to use this workaround as a fix for this issue directly, it could be used to develop a function (eventually wrapped in a plugin) to inject that dummy cookie manually.
Based on the mentioned workaround in my previous post, I have developed an additional plugin that allows to inject a dummy cookie to get the sync process started properly. While this will only work in iOS11 (and above) it solves the issue sufficiently for my client.
The repo can be found here: https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie
with the help of different people, I fixed the problem. here is the cordova plugin that might help someone else too:
https://github.com/imransilvake/Cordova-Plugin-Sync-Cookies
+1
I have the same problem with an iframe included in an Ionic application. The cookie is not used on the first time within the iframe. Is there a way I can simply fix that? This is very painful. Perhaps storing a cookie before my iframe appears.
ionic 3.20.0 - solution - https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie
npm i cordova-plugin-wkwebview-inject-cookie
ionic cordova plugin add cordova-plugin-wkwebview-inject-cookie
in app.components.ts :
declare var wkWebView: any;
...
document.addEventListener('deviceready', () => {
wkWebView.injectCookie('https://domain.com/');
});
@kbrin423, Merci bien ! Thank you very much but it's not working. I still have the problem. More precisely, I have in app.component.ts:
declare var wkWebView: any;
constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen, public events: Events, public menuCtrl: MenuController, private file: File) {
this.initializeApp();
this.pages = [
{ title: "Title", component: HomePage },
];
document.addEventListener("deviceready", () => {
console.log("Injecting cookie");
wkWebView.injectCookie("http://mydomain");
});
}
In app.html, I have:
I have ionic 3.20 and I still see the problem on my iPod touch version 11.4, aka. the cookie is not stored / accessible during the first run and if I kill/restart the app, it's correctly accessible.
Am I missing anything? (you can private me to avoid spoiling this thread).
@gregoiregentil, at the moment it's still important to add a trailing slash after your domain. Thus the call
wkWebView.injectCookie("http://mydomain");
should read
wkWebView.injectCookie("http://mydomain/");
otherwise the 'mydomain' will be treated as path.
I guess it's a bug in the plugin. So feel free to add an issue there to continue the discussion.
It seems working now. Thank you!
kbrtin423 - Thank You for taking the time to lay out the solution above. I use Wakanda on the back end, angular/ionic/cordova on the front (wakanda client in the middle), and the plugin and event listener (with a platform.is('ios') check ..... have given me the breakthrough that was necessary for me to prodeed to deployment.
There is no evident lag from this solution, no impact on the user experience.
It would be extremely helpful if this issue was at least referenced in the https://ionicframework.com/docs/wkwebview/ page. This is a pretty major limitation to WKWebView and debugging the issue is not intuitive.
Is there any solution to this issue, as I'm still facing it. Non of the provided plugins solves it, has anyone figured out a workaround? Is it planned to be fixed at any point as this is actually a dead breaker?
I guess you have tried my solution (which works at least acceptable for the company I work for). It'sa problem that it only works with iOS 11, but beyond this it should work fine. If it doesn't, please fill a bug report so that I can adress the problem.
Based on that plugin it would be possible to fix the issue in the ionic plugin, but it would require to intercept all XHRs and look for the domain just to inject a cookie for the very first access (to that domain). This will solve the issue for iOS 11, but might also slow down the performance (slightly) for all requests.
I spent the better part of 2 days on this issue, the fix by @CWBudde works for me for iOS 11, but I still need to support iOS 10. The cookie sync plugins did not work for me, maybe because my cookies all originate from xhr, or maybe because issues wrt the process pool that leaves cookies out of reach from each other(?).
But there is good news: finally I settled on this plugin by Oracle: https://github.com/oracle/cordova-plugin-wkwebview-file-xhr
It replaces the entire XMLHTTPRequest object and tunnels all xhr to native calls, thereby bypassing CORS restrictions (the goal of that plugin) but also the session cookies are now stored and transmitted correctly. I tested on iOS 10+ and that works :)
Also I should say I can not use the Ionic webview plugin, I use the cordova wkwebview plugin.
I realise that there is already a similar plugin for the Ionic webview, but I thought there could be other people with same issue that use cordova wkwebview.
Thanks @CWBudde this works for me. With 85% adoption of iOS 11 I'm going to take a chance that I won't need to accommodate iOS 10 installs but will explore @JanMisker's solution if that reality changes.
ionic 3.20.0 - solution - https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie
npm i cordova-plugin-wkwebview-inject-cookie ionic cordova plugin add cordova-plugin-wkwebview-inject-cookiein app.components.ts :
declare var wkWebView: any; ... document.addEventListener('deviceready', () => { wkWebView.injectCookie('https://domain.com/'); });
@CWBudde Thanks for the solution. For ionic can add a script tag in index.html like code below.
<script>
document.addEventListener('deviceready', () => {
wkWebView.injectCookie('mysite.com/');
}
</script>
Unfortunately, still facing an issue with Set-Cookie not actually setting them in the browser :(
I'm making a simple request with the following:
// index.js inside of Cordova application
const xhr = new XMLHttpRequest();
xhr.addEventListener('loadend', function(evt) {
console.log({ evt, response: this.response });
});
xhr.open('GET', 'http://localhost:8000/api');
xhr.send();
And here's the mockserver attaching cookies to every request:
// server.js
const cors = require('cors');
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.use(cors());
app.get('*', (req, res) => {
res.cookie('username', 'john doe', { maxAge: 900000, httpOnly: true });
res.send('Hello World!');
});
Now when I inspect the DevTools, I can see the Set-Cookies in the response but I don't see the cookies actually set in the browser.


@FarhadG You would't see the cookies if they were being set - localhost doesn't have access to localhost:8000's cookies. The cookies should still be sent with requests made to localhost:8000, localhost just can't see them because they're considered different domains. If you make a second request to localhost:8000 after the first one comes back, do the cookies show up in the header?
That makes sense, @chuckdries .
Cookies are now working for me with the v4 release of this plugin. However, setting a custom hostname and scheme doesn't. I've created this issue with a POC showcasing the issue: https://github.com/ionic-team/cordova-plugin-ionic-webview/issues/312
@CWBudde Can you explain why it's not working on IOS 10? Maybe I can patch your plugin ? Is it related to WKVIEW and NSHttpCookie ?
@maxtor3569 The problem why cookies don't work in the first place is the missing syncronization between the OS and Browser layer (see https://stackoverflow.com/a/49534854/2757879 for details).
If you set the cookie manually it is possible to trigger this mechanism in iOS 11 and latter. Unfortunately it doesn't trigger the sync process in older iOS versions. I'm not really sure why, but the plugin I wrote is not really a fix, but a dirty workaround.
In order to make it work, you have to start the sync process in a reliable way. So far I have not found any working solution, but that doesn't mean something like this exists. Especially if you go deeper in the integration, I think it's possible somehow. However, this would probably mean that you have to patch this cordova-plugin-ionic-webview plugin or add additional calls to make it work (i.e. it seems that if you pass cookies during the creation of the wkwebview in the first place it should work).
This said, we're already happy with the solution so far as older iOS versions are not much a problem for us and the behaviour with current versions is much better.
I was struggling with this issue for some time now. Gladly I've come up to a working solution with ver 4.0.0 of Ionic plugin for iOS11+. Ironically all fix is done in config.xml file itself:
<preference name="Hostname" value="marek-rulez.com" />
So no need to setting cookies manually in native wrapper. For me setting the domain solved the issue. Hope it will help someone.
Thank you very much @marecektn ! This solved the problem for me. My hostname was something like:
ionic://domain
and I changed it to
ionic://domain.net
and now it works. The API sending the cookie is on api.staging.domain.net
I was struggling with this issue for some time now. Gladly I've come up to a working solution with ver 4.0.0 of Ionic plugin for iOS11+. Ironically all fix is done in
config.xmlfile itself:
<preference name="Hostname" value="marek-rulez.com" />So no need to setting cookies manually in native wrapper. For me setting the domain solved the issue. Hope it will help someone.
@marecektn Do you have a link to any doc page on how/why this preference is used? I can't seem to find anything related to it. Thanks!
@l3ender I am not aware of any documentation about this. I've just realised it during debugging.
The github page says that Default value is localhost. Based on this knowledge you can assume, that safari syncs cookies based on domain name, therefore localhost != your-domain
Trial & error. That's why I commented on this post since it is really time consuming to find.
Thanks @marecektn that solved our issue with cookies not being persisted inside an iframe in our Ionic Capacitor app.
Thanks @marecektn
you saved my life.
I was more than a month without a solution.
sorry my english but i want to tank you
@l3ender I am not aware of any documentation about this. I've just realised it during debugging.
The github page says thatDefault value is localhost.Based on this knowledge you can assume, that safari syncs cookies based on domain name, thereforelocalhost!=your-domainTrial & error. That's why I commented on this post since it is really time consuming to find.
That's indeed a good workaround for some situations. Thank you for sharing. From iOS 13 WKWebView ignores cookies completely if the request is cross-origin. That's why I filed this Webkit bug.
Here is a good summary of cookies/XHR CORS -related issues around WKWebView from the Cordova blog: https://cordova.apache.org/news/2018/08/01/future-cordova-ios-webview.html
ionic 3.20.0 - solution - https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie
npm i cordova-plugin-wkwebview-inject-cookie ionic cordova plugin add cordova-plugin-wkwebview-inject-cookiein app.components.ts :
declare var wkWebView: any; ... document.addEventListener('deviceready', () => { wkWebView.injectCookie('https://domain.com/'); });
Thank you for the wonderful introduction of the plugin.
But I am still facing cookie persistence problem. Anyone have any idea?
Thank you very much @marecektn ! This solved the problem for me. My hostname was something like:
ionic://domain
and I changed it to
ionic://domain.netand now it works. The API sending the cookie is on api.staging.domain.net
This worked for me.
Thank you very much @marecektn
For those who are on capacitor: Just change/add this to capacitor.config.json:
"server": {
"hostname": "yourdomain.com"
}
It will change your ionic address to capacitor://yourdomain.com and cookies are passing correctly
When you will call first the same request using cordova-plugin-fetch, it will "unlock" saving set-cookie header in next normal request. That fixes issue when app is opened first time after installation. But it's not so elegant solution ;) ...
Thanks!
Here is my solution for cookie problem in ios devices
https://github.com/lucky3491/cordova-plugin-wkwebview-inject-cookie
I have tried changing the host name and the https://github.com/lucky3491/cordova-plugin-wkwebview-inject-cookie with no luck. Are there any other workarounds for this?
Thank you very much @marecektn
For those who are on capacitor: Just change/add this to capacitor.config.json:"server": { "hostname": "yourdomain.com" }It will change your ionic address to capacitor://yourdomain.com and cookies are passing correctly
Works on ios and doesn't work on android.
If "hostname" in config the same as external API hostname it does local request.
I was struggling with this issue for some time now. Gladly I've come up to a working solution with ver 4.0.0 of Ionic plugin for iOS11+. Ironically all fix is done in
config.xmlfile itself:
<preference name="Hostname" value="marek-rulez.com" />So no need to setting cookies manually in native wrapper. For me setting the domain solved the issue. Hope it will help someone.
Can i use <preference name="Hostname" value="ionic://localhost" /> in cordova ios version 6.0.0 ?
I'm having similar issues than @Elardzhi
Initially we think it could be related to allowNavigation because we have set it to the same domain, but after removing it
shows the same problem: we get a local request on android instead a remote one.
Doing some debugging on the browser through simulator, we get this reponse headers (note the shouldInterceptRequest the same as if we were using allowNavigation with the same domain)
Cache-Control: no-cache
Client-Via: shouldInterceptRequest
Content-Length: 112124
Content-Type: text/html
We need to set the androidScheme to https to avoid CORS error, like this one
Line 0 - Msg: Failed to load https://mydomain.com/app/config: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mydomain.com' is therefore not allowed access.
Our final version of capacitor.config.json server section is like this:
"server": {
"androidScheme": "https",
"hostname": "mydomain.com",
},
And same results than @Elardzhi , it works on iOS but not on android because we get a local request instead
Thank you very much @marecektn
For those who are on capacitor: Just change/add this to capacitor.config.json:"server": { "hostname": "yourdomain.com" }It will change your ionic address to capacitor://yourdomain.com and cookies are passing correctly
This actually worked for me after an excruciating amount of troubleshooting but now the problem is that users of our app are going to be making requests to potentially more than one backend which makes this particular setting useless to us. Any ideas other than using a native plugin?
Most helpful comment
I was struggling with this issue for some time now. Gladly I've come up to a working solution with ver 4.0.0 of Ionic plugin for iOS11+. Ironically all fix is done in
config.xmlfile itself:<preference name="Hostname" value="marek-rulez.com" />So no need to setting cookies manually in native wrapper. For me setting the domain solved the issue. Hope it will help someone.