2016-09-29 144 views
15

我在我的本地iPhone應用程序中,在允許登錄/註冊的網站上使用WKWebView,並將會話信息存儲在Cookie中。我正試圖弄清楚如何持久地存儲cookie信息,因此當應用程序重新啓動時,用戶仍然可以使用其Web會話。WKWebView Cookie的持久存儲

我在應用程序中有2個WKWebViews,並且它們共享一個WKProcessPool。我以一個開放的進程池:

WKProcessPool *processPool = [[WKProcessPool alloc] init];

然後對於每個WKWebView:

WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init]; 
theConfiguration.processPool = processPool; 
self.webView = [[WKWebView alloc] initWithFrame:frame configuration:theConfiguration]; 

當我登錄使用第一WKWebView,然後一段時間後,通過行動來第二WKWebView ,會話被保留,所以cookie被成功共享。但是,當我重新啓動應用程序時,會創建一個新的進程池並破壞會話信息。有什麼方法可以讓會話信息在應用程序重新啓動後持續存在?

+0

您不需要執行其他操作來保存'WKWebView'數據 - 它應該被自動保存(唯一需要澄清的是您正在使用'defaultDataStore'在配置中,因爲它只有一個保存到磁盤)。你確定會話信息在'WKWebView'中丟失了嗎?有沒有可能cookies有小ttl或別的東西?你檢查過了嗎? –

回答

9

這實際上是一個雖然因爲有一個)一些bug這仍然不是蘋果(我認爲)和b)取決於你想要什麼餅乾解決了,我想。

我不能現在來測試這一點,但我可以給你一些提示:

  1. 獲取餅乾從NSHTTPCookieStorage.sharedHTTPCookieStorage()。這一個似乎是越野車,顯然餅乾不立即保存NSHTTPCookieStorage找到它們。 People建議通過重置進程池來觸發保存,但我不知道這是否可靠工作。雖然你可能想爲自己嘗試一下。
  2. 進程池實際上並不是保存cookie的東西(儘管它定義了它們是否正確地共享)。該文件說這是WKWebsiteDataStore,所以我會看看。至少從那裏使用fetchDataRecordsOfTypes:completionHandler:來獲取cookies可能是可能的(不知道如何設置它們,但我認爲您不能僅僅因爲與進程池相同的原因而將用戶默認保存爲商店)。
  3. 如果你設法得到你需要的cookies(或者他們的價值),但不能恢復他們,我想這將是這種情況,看看here(基本上它顯示瞭如何簡單地準備與他們的httprequest,相關部分:[request addValue:@"TeskCookieKey1=TeskCookieValue1;TeskCookieKey2=TeskCookieValue2;" forHTTPHeaderField:@"Cookie"])。
  4. 如果一切都失敗,請檢查this。我知道只提供鏈接的答案不好,但我不能複製所有這些,只是爲了完整起見而添加它。

最後一件事情總的來說:我說你的成功也可能取決於cookie的類型。這是因爲this answer指出由服務器設置的Cookie不能通過NSHTTPCookieStorage訪問。我不知道這是否與你有關(但我想是的,因爲你可能正在尋找一個會話,即服務器設置的cookie,是否正確?),我不知道這是否意味着其他方法也會失敗。

如果一切都失敗了,您可能會考慮將用戶憑證保存在某處(例如鑰匙串),並在下一個應用程序開始時重新使用它們以自動進行身份驗證。這可能不會恢復所有會話數據,但考慮到用戶退出可能實際上可取的應用程序? 也許可以使用注入的腳本捕獲並保存某些值,以便以後使用,例如提到的here(顯然不是在開始時設置它們,但可能在某個時候檢索它們。當然,您需要知道網站的工作方式,當然)。

我希望至少能指引您解決問題的一些新方向。它看起來並不像應該那樣微不足道(看起來再次,會話cookie也是一種安全相關的事情,所以也許將它們從App中隱藏起來是Apple有意識的設計選擇......)。

+0

它看起來像我能夠最終在NSHTTPCookiesStorage中查看一些cookie,所以你是對的,也許只是沒有立即保存。然而,會話所需的cookie似乎並不存在,所以關於服務器端cookie的最後一點可能是發生了什麼。 – haplo1384

+0

當然,那太糟糕了。我想如果應用程序完全重新啓動,你可能不得不積極重新登錄。只要你在某處安全地存儲用戶的憑證(我建議鑰匙串,至少對於密碼)應該沒問題。當然,這並不理想,但這樣你可以請求一個具有適當HTTPRequest的新會話令牌? – Gero

-1

將信息保存在NSUserDefaults。同時,如果會話信息非常關鍵,最好將其存儲在KeyChain中。

+0

以用戶默認值存儲什麼信息? WKProcessPool不能存儲在默認值中,但是可以對其進行編碼。 – haplo1384

0

WKWebView符合NSCoding,所以你可以使用NSCoder解碼/編碼你的webView,並將其存儲在其他地方,如NSUserDefaults

//return data to store somewhere 
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:self.webView];/ 

self.webView = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
+0

謝謝,但在新應用程序啓動後從nsuserdefaults中檢索WKWebView時,網站的會話信息未保留。 – haplo1384

3

我對晚會有點遲,但人們可能會覺得這很有用。有一個解決方法,這有點煩人,但據我所知,它是唯一的解決方案,可靠地工作,至少直到蘋果修復其愚蠢的API ...

我已經花了好3天嘗試不用說,讓我無處可逃......最終,我發佈了我可以直接從服務器獲取cookie的方法。

我試圖做的第一件事就是獲得所有在WKWebView內運行的JavaScript的cookie,然後將它們傳遞給WKUserContentController,我只將它們存儲到UserDefaults。這並沒有工作,因爲我的餅乾httponly,顯然你不能得到那些JavaScript ...

我已經結束了通過在服務器端插入一個JavaScript調用頁面(Ruby on Rail在我的情況下)與餅乾作爲參數,例如

sendToDevice("key:value")

上述js函數被簡單地傳遞cookies到設備。希望這可以幫助別人保持理智......