ionic-team / cordova-plugin-ionic-webview

Web View plugin for Cordova, specialized for Ionic apps.
Apache License 2.0
486 stars 394 forks source link

Secure and HttpOnly cookies setted by server not sent to subsequent http requests #616

Open Hanzofm opened 4 years ago

Hanzofm commented 4 years ago

Hi,

I have an Ionic App with this specs:

-Ionic 3.9.2
-Angular 5.2.11
-Cordova Android 8.1.0 and iOS 5.1.1
-Cordova 8.0.0

**-cordova-plugin-ionic-webview 5.0.0** 

My app make request to a SOAP backend which is secured with a HttpOnly secure cookie JSESSIONID (Tomcat server).

I have enabled CORS so that my requests are able to reach the backend, this is the Tomcat CORS filter:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>ionic://localhost,http://localhost</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,SOAPAction,Cache-Control</param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
    </init-param>
    <init-param>
        <param-name>cors.support.credentials</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>cors.preflight.maxage</param-name>
        <param-value>10</param-value>
    </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

When I do login against the backend the server SETS a cookie (JSESSION):

Set-Cookie: JSESSIONID=00000000....; Path=/; Secure; HttpOnly

Which it would be used to send in subsequent request to backend to authenticate in secured WS. This is the code to make request with httpclient angular(Same for subsequent request)

this.http.**post**(wsurl, xml, {
        **withCredentials: true,**
        responseType: 'text',
        headers: headers,
        observe: 'response'
      })
        .toPromise()
        .then(response => {})
        .catch(err =>{})

The problem is on iOS/safari , the subsequent request not sent the Cookie Header with the JSESSIONID value. On Android, chrome works fine

A strange additional info:

Same build of app deployed on Iphone 6 iOS v12.4.5 works fine. On a iPhone X with iOS v 14 and simulators(any version) not work.

¿What would be the problem? How can I fix this?

lizqjue commented 4 years ago

Same problem here!

razam217 commented 4 years ago

Facing Same Problem with Plugin version 4.2.1. On every HTTP request, server is assigning new cookie in response. Which means cookie persistence issue. :( But only in IOS

razam217 commented 4 years ago

@Hanzofm are you also stuck here, or have found solution?

Hanzofm commented 4 years ago

Hi, I have found a temporary workaround changing the angular httpclient to https://github.com/silkimen/cordova-plugin-advanced-http plugin.

It uses the ‘credentials’ if detect it automatically

Also avoids CORS problems wich in my opinion are the main problem here

vorderpneu commented 4 years ago

Is someone of you using the cordova-plugin-wkwebview-inject-cookie plugin? Maybe that plugin is the cause of the issue and not the webview plugin --> https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie/issues/11

Hanzofm commented 4 years ago

Is someone of you using the cordova-plugin-wkwebview-inject-cookie plugin? Maybe that plugin is the cause of the issue and not the webview plugin --> CWBudde/cordova-plugin-wkwebview-inject-cookie#11

No In my case, I am not using this plugin

razam217 commented 4 years ago

@vorderpneu No, I'm also not using this plugin...

razam217 commented 4 years ago

I got this fixed via this https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie plugin. I suggest you all to try it. Hope this gets fixed for all of us.

This bug is not related to cordova-plugin-ionic-webview plugin, but its an issue with IOS Cookies Handling for WkWebView. Cookies are not synced for some devices only the first time, but for me it was not syncing forever.

samarroy commented 4 years ago

I am also facing the same issue. In subsequent request, safari is not sending the session cookie id so every time session gets renewed in the backend. I tried with https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie but the issue is still the same. I was using ios@6.0.0 then I changed to ios@6.1.0 but the issue is still the same. Can you please suggest what to do? I am using ajax to communicate with the server.

I have tried with many suggestions got from the web but no luck yet. I was testing in ios various simulators but for the devices it is same.

Kindly help me on the same if you faced the same problem and resolved the issue.

Thanks

kas84 commented 4 years ago

This is due to the way apple handles CORS cookies on wkwebview from iOS 14, they're discussing wether to implement an app bound domain list where this would be allowed in the app.

https://bugs.webkit.org/show_bug.cgi?id=213510

As a hack, I am using https://github.com/GEDYSIntraWare/cordova-plugin-ionic-webview#custom to make this requests go through native layers, but if you have other plugins that do http requests (like cordova-plugin-file-transfer) make sure that those requests don't go through this proxy.

newuser44 commented 3 years ago

I think this is the same issue I'm having upgrading to WKWebView for my ionic app.
For me this seems to only happen on the first time loading the app.
Load brand new app- Log in - debugging using safari - can see the cookies are being set in the responds request.
After login next request - This fails not knowing who is logged in -- in safari I can see that the next API call DOES NOT send cookies with the request.

Close app out and start process over, everything works as expected.

One fix is to grab the cookies and store them in local storage. This gets tricky because set-cookie header is not shown unless the requests allows it.
access-control-expose-headers: Set-Cookie

Would prefer not to do that.

vishnuvuyyur1 commented 3 years ago

As of March 2020, all third party cookies are blocked unconditionally and the third party needs to call the Storage Access API to ask for the user’s permission to use cookies. SameSite: None dosent work for macs i.e if app and server are on same domain, the cookies are sent. if they are on different domain(cross domain) cookies are not sent. Among many possible solutions, one solution is In the backend req.getHeader('user-agent') -> gives from which device the request originated Perform a check if the header contains iphone, ipad etc and set httpOnly, secure to false only for requests originating from Mac or send the token in response instead of cookie. Now in frontend you can now read the token from the response and put it in local storage and send it in the header for each next requests

newuser44 commented 3 years ago

Circling back around on this. I had things working with iOS 13. Apple rejected my app when it was run on iOS 14.
Same issue where I call my http.post. and debuting in safari I can see cookies are returned, but my next api call does not have them.
My iOS app request POST /work-json/user/login HTTP/1.1 Accept: application/json, text/plain, / Content-Type: application/json Origin: ionic://localhost Accept-Encoding: gzip, deflate, br Host: dev.test.com User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Content-Length: 152 Accept-Language: en-us Connection: keep-alive

Do I need to set up <preference name="HostName" value="myHostName" />

newuser44 commented 3 years ago

Different path. I was able to get App Bound from config.xml doing the following.

<edit-config file="*-Info.plist" mode="merge" target="WKAppBoundDomains">
        <array>
            <string>dev.test.com</string>
        </array>
    </edit-config>

Looks like this shows up correctly in info.plist Seems like I need to add the following configuration. So far unsuccessful. Hard to know what is really working.
webViewConfiguration.limitsNavigationsToAppBoundDomains = YES;

rafaellop commented 3 years ago

Try this. Works without any plugins https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie/issues/11#issuecomment-883249020

russelllee1999 commented 1 year ago

https://github.com/silkimen/cordova-plugin-advanced-http plugin. this plugin can solve sent to subsequent http requests in my cordova project