Ist es möglich, ein Cookie manuell mit sharedHTTPCookieStorage für eine UIWebView zu setzen?

73

Ich habe Webansichten in einer iOS-Anwendung, für deren ordnungsgemäße Authentifizierung ein Authentifizierungscookie erforderlich ist. Ich suche nach einer Möglichkeit, ein Cookie in der Webansicht einer iOS-Anwendung zu setzen, ohne eine ausgehende Anfrage zum Setzen des Cookies stellen zu müssen, da ich bereits Authentifizierungsinformationen auf dem Client habe.

Dieser Beitrag zeigt uns, wo die UIWebView-Cookies gespeichert sind.

Im Moment lade ich eine versteckte Webansicht, um eine ausgehende Anfrage zu stellen, möchte aber keine externe Anfrage zum Setzen eines einfachen Cookies stellen müssen.

Mauvis Ledford
quelle

Antworten:

139

Ja, das kannst du machen. Fügen Sie zunächst in applicationDidBecomeActive diese Zeile hinzu

[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];

Die CookieAcceptPolicy wird für mehrere Apps freigegeben und kann ohne Ihr Wissen geändert werden. Sie möchten also sicherstellen, dass Sie bei jeder Ausführung Ihrer App über die erforderlichen Akzeptanzrichtlinien verfügen.

So setzen Sie den Cookie:

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"testCookie" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"someValue123456" forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"www.example.com" forKey:NSHTTPCookieDomain];
[cookieProperties setObject:@"www.example.com" forKey:NSHTTPCookieOriginURL];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
[cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];

// set expiration to one month from now or any NSDate of your choosing
// 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];

Dieses Cookie hat den Namen testCookie und den Wert someValue123456 und wird mit jeder http-Anfrage an www.example.com gesendet.

Eine große Einschränkung beim Setzen von Cookies finden Sie in meiner Frage hier!

Der NSHTTPCookieStorage-Status wird beim Beenden der App nicht gespeichert. Irgendwelche definitiven Kenntnisse / Dokumentationen da draußen?

kball
quelle
NSHTTPCookieStorage implementiert sicherlich einen dauerhaften Cookie-Speicher vollständig. Es ist nur eine Frage der korrekten Einstellung der Cookie-Lebensdauer auf der Serverseite.
Bis
1
Ball, wir haben uns für diese Lösung entschieden, die Ihrer Antwort ziemlich nahe kommt: lists.apple.com/archives/Webkitsdk-dev/2003/Sep/msg00003.html
Mauvis Ledford
1
@ mauvis-ledford Wie haben Sie das erstellte Cookie dem uiwebview zugewiesen?
Ming yeow
11
Ein Cookie ist keiner Webansicht zugeordnet, sondern einer HTTP-Anforderung an eine bestimmte URL. Jede HTTP-Anfrage, ob direkt aus Ihrem Code oder aus einer Webansicht, verwendet alles, was in NSHTTPCookieStorage
kball
3
Kann jemand bestätigen, dass dies noch funktioniert? Ich habe Cookies in NSHTTPCookieStorage, aber sie scheinen für das in meinem UIWebView ausgeführte Javascript nicht verfügbar zu sein. Ich habe mit dem Webinspektor von Safari im Cookie-Shop nachgesehen und er ist leer. Jede Hilfe sehr geschätzt. iOS 10.3
Colin Whitmarsh
14

Bearbeiten: Anpassung an bearbeitete Frage

NSHTTPCookieStoragehat eine -setCookies:forURL:mainDocumentURL:Methode, daher ist es einfach , Cookies zu verwenden NSURLConnectionund zu implementieren -connection:didReceiveResponse:, sie zu extrahieren und in die Keksdose zu füllen:

- ( void )connection: (NSURLConnection *)connection
          didReceiveResponse: (NSURLResponse *)response
{
    NSHTTPURLResponse        *httpResponse = (NSHTTPURLResponse *)response;
    NSArray                  *cookies;

    cookies = [ NSHTTPCookie cookiesWithResponseHeaderFields:
                             [ httpResponse allHeaderFields ]];
    [[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
            setCookies: cookies forURL: self.url mainDocumentURL: nil ];
}

(Sie können auch einfach ein NSDictionaryObjekt aus dem NSHTTPCookiewith extrahieren propertiesund dann das Wörterbuch auf die Festplatte schreiben. Das Einlesen ist so einfach wie das Verwenden von NSDictionary's -dictionaryWithContentsOfFile:und das anschließende Erstellen des Cookies mit -initWithProperties:.)

Dann können Sie den Cookie bei Bedarf wieder aus dem Speicher ziehen:

- ( void )reloadWebview: (id)sender
{
    NSArray                 *cookies;
    NSDictionary            *cookieHeaders;
    NSMutableURLRequest     *request;

    cookies = [[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
                cookiesForURL: self.url ];
    if ( !cookies ) {
        /* kick off new NSURLConnection to retrieve new auth cookie */
        return;
    }

    cookieHeaders = [ NSHTTPCookie requestHeaderFieldsWithCookies: cookies ];
    request = [[ NSMutableURLRequest alloc ] initWithURL: self.url ];
    [ request setValue: [ cookieHeaders objectForKey: @"Cookie" ]
              forHTTPHeaderField: @"Cookie" ];

    [ self.webView loadRequest: request ];
    [ request release ];
}
mehr Spannung
quelle
1
Es ist nicht erforderlich, NSHTTPCookieStorage auf diese Weise manuell zu verwalten. Jedes Mal, wenn das URL-Ladesystem HTTP verwendet und die Cookie-Akzeptanzrichtlinie so eingestellt ist, dass Cookies akzeptiert werden, wird NSHTTPCookieStorage automatisch verwaltet. Dabei werden Cookies gespeichert, wenn sie in Antwortheadern festgelegt sind, und Header für gespeicherte Cookies beim Senden von Anforderungen festgelegt.
Ball
Sicher. Dieser Ansatz bedeutet natürlich, dass der Entwickler nicht weiß, welche Cookies bei jeder Anfrage gespeichert und gesendet werden. Dies kann unerwünscht sein, wenn die Website beispielsweise unerwünschte Tracking-Cookies setzt. Die Verwendung von NSHTTPCookieStorage kann auch eine Schwergewichtslösung sein, allerdings normalerweise nur unter Mac OS X. Siehe beispielsweise: cocoabuilder.com/archive/cocoa/…
mehr Spannung
1
Schätzen Sie die lange Antwort, obwohl es eine beträchtliche Menge an Arbeit zu sein scheint, ein einzelnes Cookie zu setzen. Am
Mauvis Ledford
7

In Swift 3 werden alle Schlüssel in die HTTPCookiePropertyKeyStruktur eingeschlossen:

let cookieProperties: [HTTPCookiePropertyKey : Any] = [.name : "name",
                                                       .value : "value",
                                                       .domain : "www.example.com",
                                                       .originURL : "www.example.com",
                                                       .path : "/",
                                                       .version : "0",
                                                       .expires : Date().addingTimeInterval(2629743)
                                                      ]

if let cookie = HTTPCookie(properties: cookieProperties) {
    HTTPCookieStorage.shared.setCookie(cookie)
}
JAL
quelle
danke, ich habe ein URL-Objekt bereitgestellt, keine Zeichenfolge für domainundoriginURL
Radu Ursache
1

Die durch iOS 10 eingeführten Einschränkungen für Cookies müssen umgangen werden, wodurch sie für verschiedene Prozesse unsichtbar werden.

Dies bedeutet, dass auf Geräten mit Multiprozessor-Funktion Webviews ein anderer Prozess sind als Ihre App. Dies bedeutet, dass Ihre "App" -Sitzung nicht mehr automatisch an die Webview übertragen wird.

Im Wesentlichen müssen Sie dies tun (selbst bei früheren Postern funktionierte es vor iOS10 automatisch).

irgendwie
quelle