16

サーバーがユーザーを識別するためのCookieを私に渡すアプリケーションを開発しています。

連続するリクエストには、ユーザーが期待する応答を得るには、そのCookieが必要です。私が理解できないのは、NSHTTPCookieStorageの共有インスタンスがいつどのようにCookieを失うかです。

私が使用した最初の解決策は、アプリケーションの終了時にサーバーからユーザーのデフォルトにCookieをアーカイブして保存し、アプリケーションの起動時にサーバーから既存のCookieをクリアして、保存したCookieをリセットすることです。デバッグのセッションは非常に短く、通常はアプリをバックグラウンドに置く必要がなかったため、開発プロセスを通じて問題は発生しませんでした。

ベータテスト中に、トラブルが発生しました。私がやってきたハックは、アプリケーションの終了時だけでなく、これらのCookieを返すAPI呼び出しの後でCookieを保存することです。また、保存されたCookieは、アプリの起動時だけでなく、アプリがフォアグラウンドに戻ったときにも読み込まれます。

NSHTTPCookieStorage共有インスタンスがこれらのCookieを削除する理由と、それを処理するためのベストプラクティスは、アプリの重要な部分であり、経験豊富な開発者によってバックアップされない限り、このようなハッキングされたソリューションを信頼することはできません。

よろしくお願いします

編集:Cookieを保存/読み取り/クリアする方法は次のとおりです

-(void)saveStoredCookies
{
    NSURL *httpUrl = @"http://myServer.com";
    NSURL *httpsUrl = @"https://myServer.com";

    NSArray *httpCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpUrl];
    NSData *httpCookiesData = [NSKeyedArchiver archivedDataWithRootObject:httpCookies];
    [[NSUserDefaults standardUserDefaults] setObject:httpCookiesData forKey:@"savedHttpCookies"];

    NSArray *httpsCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpsUrl];
    NSData *httpsCookiesData = [NSKeyedArchiver archivedDataWithRootObject:httpsCookies];
    [[NSUserDefaults standardUserDefaults] setObject:httpsCookiesData forKey:@"savedHttpsCookies"];

    [[NSUserDefaults standardUserDefaults] synchronize];
}

-(void)readStoredCookies
{
    //clear, read and install stored cookies
    NSURL *httpUrl = @"http://myServer.com";
    NSURL *httpsUrl = @"https://myServer.com";

    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpUrl];
    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }
    cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpsUrl];
    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }

    NSData *httpCookiesData = [[NSUserDefaults standardUserDefaults] objectForKey:@"savedHttpCookies"];
    if([httpCookiesData length]) {
        NSArray *savedCookies = [NSKeyedUnarchiver unarchiveObjectWithData:httpCookiesData];
        for (NSHTTPCookie *cookie in savedCookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }       
    }
    NSData *httpsCookiesData = [[NSUserDefaults standardUserDefaults] objectForKey:@"savedHttpsCookies"];
    if([httpsCookiesData length]) {
        NSArray *savedCookies = [NSKeyedUnarchiver unarchiveObjectWithData:httpsCookiesData];
        for (NSHTTPCookie *cookie in savedCookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }       
    }
}

-(void)clearStoredCookies
{
    NSURL *httpUrl = @"http://myServer.com";
    NSURL *httpsUrl = @"https://myServer.com";
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpUrl];
    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }
    cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpsUrl];
    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }
}
4

4 に答える 4

21

NSHttpCookieStorage は、Cookie の有効期限を設定していないため、Cookie を失います。有効期限を設定する必要があります。そうしないと、アプリの終了時に Cookie が失われます。

これは、アプリの終了時と起動時に Cookie を保存する方法を簡単に示したものです。

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:name forKey:NSHTTPCookieName];
[cookieProperties setObject:strValue forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"myserver.com" forKey:NSHTTPCookieDomain];    // Without http://
[cookieProperties setObject:@"myserver.com" forKey:NSHTTPCookieOriginURL]; // Without http://
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];

// set expiration to one month from now or any future NSDate of your choice
// this makes the cookie sessionless and it will persist across web sessions and app launches
/// if you want the cookie to be destroyed when your app exits, don't set this
[cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];

NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

お役に立てれば。

于 2012-08-10T04:15:39.823 に答える
7

これはシミュレーターですか?ローリングクッキーを使用していますか?

シミュレーターでは、Cookie はデスクトップの Safari と共有されているため、実際には保持されません。Cookie がロールオーバーすると、最終的に一方が他方を上書きします。

これは、各アプリに独自の Cookie ストアがあるデバイス自体の問題ではありません。(そして、正直なところ、Mountain Lion でそれが起こっていることにまだ気づいていません。)

于 2012-08-11T04:06:36.333 に答える
1

フマーユーンは正しいかもしれません-

ただし、NSUserDefaultsにCookieを書き込むべきではありません-

sharedHTTPCookieStorageの要点は、そこからそれらを読み取ることです。

NSArray *httpCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpUrl];

セキュリティ上の理由から、これらのCookieをNSUserDefaultsに書き込むことさえできないはずです。しかし、多分あなたはそうすることができます。いずれにせよ、フマーユーンが述べたようにタイムアウトが設定されなかった可能性があります。

いずれにせよ、コードをリファクタリングし、ユーザー設定にCookieを保存しようとしないでください。

于 2012-08-10T15:12:52.690 に答える
0

解決しました!

簡単なデバッグを行った後、問題は で使用していた URL にあることがわかりましたcookiesForURL:。私はプロパティを使い始めたcookiesばかりで、今ではうまく機能しています。

于 2012-10-02T14:12:36.353 に答える