在应用程序重新启动时,inappbrowser iOS 10 中的缓存 Cookie(clearcache=no;)不起作用 - Cordova/Ionic

Posted

技术标签:

【中文标题】在应用程序重新启动时,inappbrowser iOS 10 中的缓存 Cookie(clearcache=no;)不起作用 - Cordova/Ionic【英文标题】:Caching Cookies in inappbrowser iOS 10(clearcache=no;) not working when app restarts - Cordova/Ionic 【发布时间】:2017-02-05 21:52:09 【问题描述】:

我在 ionic ios 应用程序中遇到问题,我的网站没有保存 cookie,并且清除缓存和清除会话缓存不起作用。 我正在使用 Cordova Inappbrowser 插件。

android 中,它运行良好。

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

但是,在 iOS 中,它不起作用。什么时候,我首先提供我的凭据,然后进入应用程序,然后我退出应用程序并重新打开它,它会再次询问我的凭据(在 ANDROID 中完美运行)

经过进一步挖掘,我发现原本要保存的cookie被标记为isSessionOnly=true and expires=null

因此,我可以在会话中看到 cookie,但在应用关闭时会被清除

我通过在 CDVinAppbrowser.m 类中编写以下代码找到了我的结果:

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

那么,如何在 iOS 中保存 cookie 或使用 clearcache=no 和 clearsessioncache=no 选项制作 inappbrowser。

注意:我对 iOS/Swift 完全陌生。所以,我需要知道将代码放在 swift 类中的什么位置。

为赏金编辑(AndroidMechanic)

我遇到了完全相同的问题,它完美地适用于 android,但在 iOS 上,每次应用重新启动时都会要求提供凭据。我正在为可以避免使用本机代码的解决方案提供悬赏。

【问题讨论】:

这个问题你解决了吗? 您找到解决方案了吗?我也面临同样的问题 @AndroidMechanic 看起来像一个错误,你能提供一个可以轻松复制的示例吗? @AndroidMechanic OP 已根据此处的链接使用 cordova cookie Emperor 插件解决了此问题 - forum.ionicframework.com/t/… @AndroidMechanic 你检查过这个吗? 【参考方案1】:

详细说明@Sourav Das 的答案,以便对其他人有用。

如果您的身份验证方案仅基于 SAML,则您别无选择,只能依赖身份提供者设置的 cookie。

IdP 设置的 cookie 通常是 sessionOnly cookie,没有任何到期日期。 Android WebView 在应用程序重新启动(终止和重新打开)之间保存这些 sessionOnly cookie 以及其他 cookie(即具有到期日期),但基于 iOS 的 WebView 不保存 sessionOnly cookie。 iOS 中仅保存有过期日期的 cookie。

如果 iOS 应用程序开发人员的意图是在应用程序重新启动之间保留 sessionOnly cookie - 有两种方法可以做到这一点。

    根据https://***.com/a/5938927/6243处的逻辑实现自定义cordova插件

    如果您知道设置 sessionOnly cookie 的确切名称,请使用 Cookie Emperor plugin。您可以在 javascript 层使用此插件进行读/写,而不是处理原生 iOS 代码。

【讨论】:

【参考方案2】:

@AndroidMechanic ,您为 iOS 指定的问题是一个已知问题,我们也遇到了同样的问题,因此我们提出了以下解决方案,而不是将详细信息保存在 Session 或 Cookies 中,我们更喜欢保存在 KeyChain这是支持Ionic Native 的参考链接。

1.安装 Cordova 和 Ionic Native 插件:

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

2.将此插件添加到您应用的模块中 ...

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

...

@NgModule(
  ...

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

3.用法

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));

【讨论】:

【参考方案3】:

@AndroidMechanic, 我发布了这个问题,我们就是这样解决的。

我们认为 iOS inappbrowser webview 不能正确处理 cookie,但 android 的 webview 可以。 我们的应用程序的初始登录过程是通过我们的身份提供者(在我们的例子中是 ADFS)。身份提供者是通过 SAML 配置的(通过 Cookie 工作)。

解决方案 1:(确保 Cookie 只要有效就可以工作)

因此,我们使用了 cordova 插件 cookiemperor,我们在成功登录后保存了 cookie,并在任何人再次登录时将其传递给 URL。这一直有效,直到 cookie 没有过期。

但是,我们需要一个更好的解决方案来解决这个问题,即解决方案 2。

解决方案 2:(不要使用 Cookie,使用访问令牌)

我们将身份验证从 SAML 更改为 OAuth2.0 授权代码流协议,其中我们使用访问令牌和刷新令牌来验证用户的身份。

因此,无论何时触发登录控制器,它都会在调用 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.

如果上述任一条件失败,我们将调用用户必须再次登录的 URL,否则用户可以在 iOS 和 Android 中使用 SSO 功能,而无需担心 cookie。

谢谢

苏拉夫

【讨论】:

不幸的是,我无法将身份验证模式从 SAML 更改为 OAuth2.0,因此仍需要处理 cookie。我在 iOS 上遇到了完全相同的问题,而在 Android 上的流程运行得非常好。您能否详细说明一下 Cookie Emperor 将如何解决这个问题?我知道使用 Cookie Emperor 我们可以在成功登录后保存 cookie,但是接下来在打开 inAppBrowser 时如何传递呢? 我通过阅读 SO - ***.com/questions/2662530/… 中的这篇文章得到了我的问题的答案,基本上 isSessionOnly=true 类型的 NSHTTPCookie 不会在应用程序重新启动之间保存。如果我们需要该功能,我们可以在本机级别引入此行为,编写自己的 cordova 插件,或者在 javascript 级别使用 cookie Emperor 等插件。【参考方案4】:

我最近在 iOS(Safari) 上遇到了这个问题。 Android(Chrome) 清除缓存,但 iOS(Safari) 不清除,它使用以前的数据。我找到了解决方案。如果调用服务时参数每次都会改变,iOS(Safari) 和 Android(Chrome) 不会使用之前的数据。您不需要在后端使用此变量。这样问题就解决了。

import  SERVER_URL  from 'src/environments/environment';

@Injectable(
  providedIn: 'root'
)
export class DataService 

  headers: any = new HttpHeaders(
    'Cache-Control': 'no-cache, no-store, must-revalidate, post- check=0, pre-check=0, max-age=0, private, max-stale=0',
    Pragma: 'no-cache',
    Expires: '0'
  );

  xxx = 0;

  constructor(public http: HttpClient) 

  

  getAlarms() 
    this.xxx += 1;
    if (this.xxx >= 50) 
      this.xxx = 0;
    
    return this.http.get('http://' + SERVER_URL + '/alarms?xxx=' + this.xxx,  headers: this.headers );
  


【讨论】:

以上是关于在应用程序重新启动时,inappbrowser iOS 10 中的缓存 Cookie(clearcache=no;)不起作用 - Cordova/Ionic的主要内容,如果未能解决你的问题,请参考以下文章

InAppBrowser 未启动

在 webview 中加载网页时如何启动 inappbrowser

Cordova/Phonegap 通过 JavaScript inappbrowser 打印

Cordova InAppBrowser 在 iPad iOS 10 上为空白

在 InAppBrowser 中打开链接时维护标题

如何在控制器加载时立即显示 InAppBrowser 的实例,而 Ionic 应用程序不会无响应?