Pass a session cookie through an iFrame on iOS

Hi everyone,

After migrating our Ionic-Angular app from Cordova to Capacitor, i noticed that we can’t log the user through an iframe with a session cookie on iOS. the page being loaded in the iframe is one of our subdomain and it work well on PWA (all browsers including Safari), and Android.

But for iOS, i have the following error message :

Blocked a frame with origin “https://domain.com” from accessing a frame with origin “capacitor://domain.com”. The frame requesting access has a protocol of “https”, the frame being accessed has a protocol of “capacitor”. Protocols must match.

I’ve seen that we can’t pass https nor http to iosScheme ( just as i did for android ), because it’s reserved for WKWebView, so what can we do instead ?

Actually, we pass a the session in the url of the iframe being loaded and it’s the http.d conf of the subdomain that set the cookie for us but unfortunately it doesn’t work on iOS and the user is just redirects on the auth page;

i also tried with a postMessage, but it seems I get redirected before I can receive the message…

This is a part of my capacitor.config.ts :

ios: {
    contentInset: "always",
    scheme: "AppName",
    limitsNavigationsToAppBoundDomains: true
  },
  server: {
    hostname: "domain.com",
    androidScheme: "https",
    allowNavigation: ["subdomain.domain.com", ".domain.com", "domain.com"]
  }

This is a part of my info.plist :

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
<key>WKAppBoundDomains</key>
<array>
    <string>domain.com</string>
    <string>.domain.com</string>
    <string>subdomain.domain.com</string>
</array>

Ionic Framework : 5.3.1
Capacitor Core: 3.2.4
Capacitor iOS : 3.1.2

1 Like

Is there really nobody that as to deal with something like that ?

Did you have solution for this??

There’s an open issue on Capacitor for iOS Cookie problems that the Capacitor team has been talking a lot internally about how to fix. It’s a difficult problem to fix universally without breaking the existing solutions developers have. If we can fix it in the 3.x release, we will. But if it’s a breaking change, it will be a 4.0 release (which we’ve started some basic planning for!)

That being said; there are a couple of things you could try.

Hi @thomasvidas , thanks for responding ! :slight_smile:

  • I must not quit the app while opening this page, so i can’t really use the SFSafariViewController…

  • Actually, I pass the session-cookie in the url that i want to open, and this is the http.d conf of the site beeing displayed in the iframe that sets the cookie ( which is on subdomain.domain.com while i came from domain.com ).
    I must have this cookie to pass the firewall otherwise i get rejected… i read a lot about wkwebview blocking cookie from another domain since iOS 14, but didn’t find any solution to my problem.
    Actually maybe i can try to set the cookie with he Http Plugin wihtin the main app ( before launching the iframe ), but I’m not reaaly sure this can works due to the differences in the domain.

  • Concerning the last solution, i tried this approach ([IOS] Cookies problems in IOS · Issue #1373 · ionic-team/capacitor · GitHub) but didn’t get it to work properly…
    i will look for this solution, and come back here later, thanks !

any solution found for this issue please?

Hi Stafield & skysky,

Actually, i managed to do it by setting it twice, one in http.d conf and the other in the client iframe.
The conf of capacitor is the same as in the first post.

It is currently working with the subdomain.domain.com, i don’t know if you can get it working with a completely different domain.

Hi @SachaDuGardon, can you explain more thoroughly how you accomplished this?
I’m in a position where I must pass a session cookie through an iframe, but I’m completely lost.

Hi @miguel2650,

In the Angular app which is displaying the iframe, i just passe the URL i want to open in the iframe with the session token as a parameter :
return ${this.url}answer?answerToken=${token}&cookie=${this.cookieSession};

In the http.d conf.d i’ve got this to handle the cookie too :

  <Directory "/srv/sites/app/preprod">   
    Require all granted

    Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
    Header always set Access-Control-Max-Age "1000"
    Header always set Access-Control-Allow-Headers "*"

    <If "%{QUERY_STRING} =~ /cookie/">
    RequestHeader set Cookie %{QUERY_STRING}s
    RequestHeader edit Cookie .*cookie=([^&]*) $1
    Header always set Display-Cookie %{QUERY_STRING}s
    Header always edit Display-Cookie .*cookie=([^&]*) $1
  </If>
  <Else>
    RequestHeader set Cookie %{HTTP:Display-Cookie}s
    Header always set Display-Cookie %{HTTP:Display-Cookie}s
  </Else>

In the VueJS frontend which is being displayed in the iframe, i get the cookie like this :
const cookie = this.$route.query.cookie;

And i’m setting it using axios ( this is the http client we use for the project ) :
axios.defaults.headers.common["Display-Cookie"] = cookie;