2011-05-10 9 views
69

Tengo vistas de web dentro de una aplicación de iOS que requieren una autenticación autenticada. Estoy buscando una forma de establecer una cookie dentro de la vista web de una aplicación de iOS sin tener que realizar una solicitud de salida para establecer la cookie ya que ya tengo información de autenticación en el cliente.¿Es posible establecer una cookie manualmente usando sharedHTTPCookieStorage para UIWebView?

Este post nos muestra dónde se almacenan las cookies de UIWebView.

Ahora estoy cargando una vista web oculta para realizar una solicitud de salida pero preferiría no tener que realizar una solicitud externa para establecer una cookie simple.

Respuesta

128

sí, se puede hacer esto. En primer lugar, en applicationDidBecomeActive añadir esta línea

[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; 

El cookieAcceptPolicy se comparte a través de aplicaciones y puede ser cambiado sin su conocimiento, por lo que desea asegurarse de que tiene la política de aceptar lo que necesita cada vez que su aplicación se está ejecutando.

Entonces, para fijar la 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]; 

Esta cookie tiene el nombre y el valor TestCookie someValue123456 y será enviado con cualquier petición http a www.example.com.

Para una gran advertencia sobre el establecimiento de cookies, ¡por favor vea mi pregunta aquí!

NSHTTPCookieStorage state not saved on app exit. Any definitive knowledge/documentation out there?

+0

NSHTTPCookieStorage ciertamente implementa completamente un almacenamiento persistente de cookies. Solo se trata de establecer la duración de la cookie correctamente en el lado del servidor. – Till

+0

Sí implementa un almacenamiento persistente de cookies. El único problema es que falla cuando la aplicación se cierra poco después de que se establece la cookie. – kball

+1

Ball, terminamos yendo con esta solución que está muy cerca de su respuesta: http://lists.apple.com/archives/Webkitsdk-dev/2003/Sep/msg00003.html –

14

Editar: adaptándose a la pregunta editada

NSHTTPCookieStorage tiene un método -setCookies:forURL:mainDocumentURL:, por lo que la cosa fácil de hacer es usar NSURLConnection e implementar -connection:didReceiveResponse:, extraer las galletas y metiéndolos en la caja de galletas:

- (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 ]; 
} 

(También puede extraer un objeto NSDictionary del NSHTTPCookie con properties y luego escribir el diccionario en el disco. Leerlo de nuevo es tan fácil como usarlo . NSDictionary 's -dictionaryWithContentsOfFile: y luego la creación de la cookie con -initWithProperties:)

entonces se puede tirar de la cookie de vuelta fuera del almacenamiento cuando lo necesite:

- (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 ]; 
} 
+1

No hay necesidad de manejar manualmente NSHTTPCookieStorage esta manera. Cada vez que el sistema de carga de URL utiliza HTTP y la política de aceptación de cookies está configurada para aceptar cookies, NSHTTPCookieStorage se administra automáticamente, almacenando cookies si se configuran en encabezados de respuesta y estableciendo encabezados para cookies almacenadas al enviar solicitudes. – kball

+0

Sure. Por supuesto, ese enfoque significa que el desarrollador ignora qué cookies se guardan y envían con cada solicitud, lo que puede ser indeseable si, por ejemplo, el sitio está configurando cookies de seguimiento no deseadas. Usar NSHTTPCookieStorage en absoluto puede ser una solución de peso pesado, también, aunque normalmente solo en Mac OS X. Por ejemplo, ver: http://www.cocoabuilder.com/archive/cocoa/169235-nsurlconnection-without-nshttpcookiestorage.html –

+1

Apreciar la respuesta larga, aunque parece ser una cantidad considerable de trabajo establecer una sola cookie. Terminamos haciendo esto: http://lists.apple.com/archives/Webkitsdk-dev/2003/Sep/msg00003.html –

1

existe la necesidad de evitar las limitaciones de las cookies introducidas por el IOS 10, que hace invisibles a los diferentes procesos.

Esto significa que en los dispositivos con capacidad de multiprocesamiento, las vistas web son un proceso distinto que su aplicación, lo que significa que su sesión de "aplicación" ya no se transmite automáticamente a la vista web.

Así que, en esencia, tendrá que hacerlo (incluso los carteles anteriores donde estaba bien, estaba trabajando automáticamente antes de iOS10).

3

En Swift 3 todas las teclas están envueltos en el HTTPCookiePropertyKey estructura:

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) 
} 
Cuestiones relacionadas