3

デバイス側に保存されたセッション Cookie を使用して http リクエストを送信しています。問題は、アプリの終了後もそれを維持したいということです。しかし、私のアプリのすべての Cookie が削除されたようです。シミュレーターとデバイスの両方で試してみましたが、同じ動作が得られました。

この Cookie の削除を防ぐ iOS の方法はありますか? そうでない場合、ディスクに保存して元に戻すにはどうすればよいですか?

セキュリティのために、この Cookie を iOS キーチェーンに保存する予定です。そして、すべての NSHTTPCookie プロパティを安全に NSString に変換できると思います。したがって、私の現在のアイデアは、NSHTTPCookie -> NSDictionary -> String -> Save in Keychainから変換し、元の Cookie を取得するために戻って使用することです。問題は、 NSDictionary -> Stringを変換し、 String -> NSDictionaryを解析するという面倒なことをしたくないということです。

4

3 に答える 3

2

これを行うためのきれいな方法を見つけました。トリックは、JSONKit(RestKit に付属している) を使用して、JSON 形式を使用して NSString と NSDictionary の間で変換することです。そして、ここで私SFHFKeychainUtilsはキーチェーンのものを手伝うために使用します. このように、Cookie の各プロパティとすべての変換作業について心配する必要はありません。:)

#import "RestKit/JSONKit.h"

#define WSC_serviceName @"WSC_serviceName"
#define WSC_username    @"WSC_username"
#define WSC_cookieName  @"_your_cookie_name" // name of the session cookie

- (void)saveSessionCookieToKeyChain {
    for (NSHTTPCookie *c in [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies) {
        if ([c.name isEqualToString:WSC_cookieName]) {
            NSString *cookieString = [c.properties JSONString];
            NSLog(@"cookieString: %@",cookieString);
            NSError *saveError = nil;
            [SFHFKeychainUtils storeUsername:WSC_username
                                 andPassword:cookieString 
                              forServiceName:WSC_serviceName 
                              updateExisting:YES error:&saveError];
        }
    }
}

- (BOOL)readsSessionCookieFromKeyChain {
    NSError *readError = nil;
    NSString *jsonString = [SFHFKeychainUtils getPasswordForUsername:WSC_username
                                                      andServiceName:WSC_serviceName 
                                                               error:&readError];
    if (!jsonString) return NO;
    NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; // be sure that data is in UTF8 or it won't work
    JSONDecoder* decoder = [[JSONDecoder alloc] initWithParseOptions:JKParseOptionNone];
    NSDictionary* jsonDict = (NSDictionary*)[decoder objectWithData:jsonData];
    NSLog(@"jsonDict: %@",jsonDict);

    NSHTTPCookie *cookie = [[NSHTTPCookie alloc] initWithProperties:jsonDict];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

    return cookie!=nil;
}

- (void)clearSessionCookieAndRemoveFromKeyChain {
    for (NSHTTPCookie *c in [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:c];
    }
    NSError *deleteError = nil;
    [SFHFKeychainUtils deleteItemForUsername:WSC_username 
                              andServiceName:WSC_serviceName 
                                       error:&deleteError];
}
于 2012-05-22T10:47:46.947 に答える
1

===== まとめ =====

さて、NSDictionary を永続化するための可能な方法を要約するために、別の回答を作成します (もちろんオブジェクトは含まれません!)。

これを行う最も簡単な方法は、NSDictionary のwriteToFile:メソッドを使用することです。これにより、plist ファイルが生成されます。(NSArray でも利用可能) セキュリティが心配な場合は、配列を NSData オブジェクトに暗号化して記述します。

もっとも速い方法ではありませんが、ツールを使用して NSDictionary を JSON や XML などの文字列形式に変換する方法もあります。この文字列を iOS キーチェーンに保存して、後で簡単に取得できます。(SFHFKeychainUtilsキーチェーンの作業を支援するのに最適です)。キーチェーンを使用する利点は、自動的に暗号化されることです。

于 2012-05-23T11:17:14.243 に答える
1

NSHTTPURLResponse があると仮定すると、次のような Cookie の配列を取得できます。

NSDictionary * headers = [(NSHTTPURLResponse *)response allHeaderFields];
NSArray * cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:response.URL];

responseNSHTTPURLResponse はどこにありますか。

NSURLConnectionDelegate のこれら 2 つのメソッドで NSURLResponses を取得します。

- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

NSHTTPCookie にはpropertiesを返すプロパティがあるNSDictionaryので、それらを保存できます。その後、同じ辞書を使用して作成できます-initWithProperties:

それらを送信するには、 の Cookie ヘッダー用に独自の文字列を作成する必要がありますNSURLRequest。何かのようなもの:

NSMutableString * cookieString = [[NSMutableString alloc] init];
for (NSHTTPCookie * cookie in myLoadedCookies){
    [cookieString appendFormat:@"%@=%@; ", cookie.name, cookie.value];
}
[request setValue:cookieString forHTTPHeaderField:@"Cookie"];
[cookieString release];

はどこrequestにありますかNSMutableURLRequest

また、iOS による Cookie 自体の管理を必ず停止する必要があります。

[request setHTTPShouldHandleCookies:NO];
于 2012-05-21T11:42:09.957 に答える