Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching Cookies in inappbrowser iOS 10(clearcache=no;) not working when app restarts - Cordova/Ionic

I am facing an issue in an ionic iOS application where my website is not saving cookies and clear cache and clear session cache are not working. I am using Cordova Inappbrowser plugin.

In Android, it is working perfectly.

var ref = window.open(url, '_blank','location=no,toolbar=yes,clearcache=no,clearsessioncache=no');

But, in iOS, it is not working. When, I first provide my credentials, and go into the app and then I exit the app and reopen it, it again asks for my credentials( Which works perfectly in ANDROID )

Upon further digging, I found that the cookie which was meant to be saved are marked as isSessionOnly=true and expires=null.

Thus, I can see the cookie inside the session but gets cleared when an app is closed

I found my result by writing the following code in CDVinAppbrowser.m class:

- (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options
   {     
       NSHTTPCookie *cookie;
       NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (cookie in [cookieJar cookies]) {
       NSLog(@"%@", cookie);
    }

So, how to save cookies or make the inappbrowser with options working with clearcache=no and clearsessioncache=no in iOS.

Note: I am completely new to iOS/Swift. So, I need to know where to place the code in the swift classes.

Edit for Bounty (by AndroidMechanic)

I have the exact same problem where it works for android flawlessly but on iOS it asks for credentials every time the app restarts. I'm offering a bounty for a solution where native code can be avoided.

like image 601
Sourav Das Avatar asked Feb 05 '17 21:02

Sourav Das


3 Answers

Elaborating on answer from @Sourav Das so that it may be useful for others.

If your authentication scheme is only SAML based you do not have any option but depend on cookies set by the Identity Provider.

The cookies set by IdPs generally are sessionOnly cookies without any expiry date. Android WebView saves these sessionOnly cookies along with other cookies(i.e. with expiry dates) between app restarts (kill and reopen) but iOS based WebViews do not save sessionOnly cookies. Only cookies with expiry date are saved in iOS.

If the intention of iOS app developer is to retain the sessionOnly cookies as well between app restarts - there are 2 ways to do this.

  1. Implement a custom cordova plugin based on the logic at https://stackoverflow.com/a/5938927/6243

  2. Use Cookie Emperor plugin if you know the exact name by which your sessionOnly cookies will be set. You can read/write using this plugin at JavaScript layer instead of dealing with native iOS code.

like image 193
Varun Avatar answered Sep 30 '22 02:09

Varun


@AndroidMechanic , the problem you specified for the iOS is a Known Issue and We faced the same so we came up with the following solution, instead of saving the details in the Session or Cookies , we preferred to save in KeyChain Here is the Reference link which supports the Ionic Native .

1.Install the Cordova and Ionic Native plugins:

$ ionic cordova plugin add cordova-plugin-ios-keychain
$ npm install --save @ionic-native/keychain

2.Add this plugin to your app's module ...

import { Keychain } from '@ionic-native/Keychain';

...

@NgModule({
  ...

  providers: [
    ...
    Keychain 
    ...
  ]
  ...
})
export class AppModule { }

3. Usage

import { Keychain } from '@ionic-native/keychain';

constructor(private keychain: Keychain) { }

...

this.keychain.set(key, value).then(() => {
  this.keychain.get(key)
    .then(value => console.log('Got value', value))
    .catch(err => console.error('Error getting', err));
})
.catch(err => console.error('Error setting', err));
like image 36
Tummala Krishna Kishore Avatar answered Sep 30 '22 01:09

Tummala Krishna Kishore


@AndroidMechanic, I posted the question and this is how we solved it.

We figured that iOS inappbrowser webview does not handle cookies properly but android's webview does. Our App's Initial Login Process was via our Identity Provider( Which was ADFS in our case ). The Identity Provider was configured via SAML( Which works via Cookies).

Solution 1: (Make Sure Cookies work as long they are valid)

So, we used cordova plugin cookiemperor where we saved the cookie after a successful login and passed that to the URL whenever anyone logs in again. This worked till the cookie was not expiring.

But, we needed a better solution to this problem which is Solution 2.

Solution 2: (Don't use Cookies, Use Access Token )

We changed our Authentication from SAML to OAuth2.0 Authorization Code Flow protocol where we used Access Tokens and Refresh Tokens to verify the identity of the user.

So, whenever Login Controller is fired, it checks the following before calling the URL:

A) Check if any access token is present
B) If present, whether it is expired or not.
C) If expired, use the refresh token to get the new access token.

If any of the above conditions fail, we call the URL where user has to log in again otherwise user can utilize the SSO Capabilities in both iOS and Android without worrying about cookies.

Thanks

Sourav

like image 22
Sourav Das Avatar answered Sep 30 '22 02:09

Sourav Das