signin google con auth autenticar addstatedidchangelistener objective-c cocoa nsurlconnection nsurlcredential

objective c - google - No se puede volver a autenticar con diferentes NSURLCredentials(se usan las antiguas eliminadas)



firebase swift 4 auth (6)

He estado buscando stackoverflow, google, apple y otros lugares. Los consejos proporcionados parecen prometedores, los implementé pero, en general, no parecen funcionar ni se hacen cumplir.

Problema: Tengo una NSURLConnection con credenciales específicas. Luego tengo un cierre de sesión en el que sharedHTTPCookieStorage las sharedHTTPCookieStorage el sharedHTTPCookieStorage protección, sharedHTTPCookieStorage todas las respuestas almacenadas en caché y borro todas las cookies en el sharedHTTPCookieStorage pero cuando sharedHTTPCookieStorage llamar mi solicitud autenticada unos segundos más tarde, incluso con las credenciales incorrectas, todavía estoy usando la antigua (eliminada) cartas credenciales

Aquí hay algunos extractos de código, donde se eliminan las credenciales

NSDictionary *credentialsDict = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials]; if ([credentialsDict count] > 0) { // the credentialsDict has NSURLProtectionSpace objs as keys and dicts of userName => NSURLCredential NSEnumerator *protectionSpaceEnumerator = [credentialsDict keyEnumerator]; id urlProtectionSpace; // iterate over all NSURLProtectionSpaces while (urlProtectionSpace = [protectionSpaceEnumerator nextObject]) { NSEnumerator *userNameEnumerator = [[credentialsDict objectForKey:urlProtectionSpace] keyEnumerator]; id userName; // iterate over all usernames for this protectionspace, which are the keys for the actual NSURLCredentials while (userName = [userNameEnumerator nextObject]) { NSURLCredential *cred = [[credentialsDict objectForKey:urlProtectionSpace] objectForKey:userName]; WriteLog(@"Method: switchView removing credential %@",[cred user]); [[NSURLCredentialStorage sharedCredentialStorage] removeCredential:cred forProtectionSpace:urlProtectionSpace]; } } }

Luego elimino todas las respuestas en caché

NSURLCache *sharedCache = [NSURLCache sharedURLCache]; [sharedCache removeAllCachedResponses];

Luego borro todas las cookies

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; NSArray *cookies = [cookieStorage cookies]; for (NSHTTPCookie *cookie in cookies) { [cookieStorage deleteCookie:cookie]; NSLog(@"deleted cookie"); }

También intenté no usar cookies y otras políticas

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0]; [request setHTTPShouldHandleCookies:NO]; if(self.currentCookies != nil){ [request setAllHTTPHeaderFields: [NSHTTPCookie requestHeaderFieldsWithCookies:nil]]; } theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

También intenté esta sugerencia aquí específicamente para almacenar las cookies y pasarlas de nuevo. http://www.hanspinckaers.com/multiple-nsurlrequests-with-different-cookies . Hay otro blog en la web que sugiere agregar un "#" a cada URL para hacer cumplir la reautenticación, que funciona pero no resuelve el problema porque necesito contar con las credenciales de la sesión y la capacidad de usar credenciales totalmente diferentes.

¿Se trata de un error o problema conocido y cómo resuelvo esto realmente ... En pocas palabras: en qué me estoy equivocando exactamente aquí?

Esto realmente me está molestando y me impide continuar con mi trabajo.

¡Apreciaría mucho cualquier entrada!

¡Muchas gracias!


Acabo de encontrarme con este problema con AFNetworking. Estoy trabajando con un backend que requiere la autorización para pasar en el encabezado. Sin embargo, cuando el usuario cierra la sesión de la aplicación e intenta volver a iniciarla (incluso con credenciales diferentes) recibí un error del servidor. Mi solución fue borrar las cookies de mis aplicaciones cuando borro el encabezado de autenticación en el cierre de sesión.

- (void)clearAuthorizationHeader { [self.manager.requestSerializer clearAuthorizationHeader]; NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (NSHTTPCookie *cookie in [storage cookies]) { [storage deleteCookie:cookie]; } }


Desafortunadamente, no parece haber una solución a este problema.

Puede usar NSURLCredentialPersistenceNone o el # trick o puede definir el método delegado ''connectionShouldUseCredentialStorage'' para devolver NO. Si lo haces cada vez y tu aplicación nunca conserva las credenciales para una sesión, eso forzará el desafío a ocurrir en cada solicitud.

Para aplicaciones que solo realizan solicitudes mínimas o que terminan utilizando una cookie de sesión para la autenticación, eso podría funcionar bien.

Para las aplicaciones que envían un gran número de solicitudes, todas estas soluciones dan como resultado una respuesta 401 para cada solicitud individual y esa respuesta-desafío adicional puede sumar en términos de datos y rendimiento.

Sería bueno si pudiera conservar el almacenamiento de credenciales para la sesión hasta que necesitara cerrar sesión y luego cambiar a una de las soluciones, pero eso no es posible.

Tan pronto como almacena las credenciales una vez para una sesión, se almacenan en caché para toda la sesión TLS. Eso da como resultado la necesidad de esperar unos 10 minutos hasta que la sesión desaparezca.

Puede leer más sobre este problema en: http://developer.apple.com/library/ios/qa/qa1727/_index.html

Ese documento menciona una solución limitada que implica agregar un ''.'' hasta el final del nombre del servidor. Sin embargo, no he podido conseguir que funcione.

Aparte de eso, estas son las soluciones que se me ocurren:

1) Siempre use la solución alternativa NSURLCredentialPersistenceNone & connectionShouldUseUseCredentialStorage que debe generar el 401s. Agregue el encabezado de autenticación básica a la solicitud, usted mismo. Esto debería evitar que los 401 adicionales omitan el almacenamiento de credenciales. El código para agregar esa autorización es algo como esto:

NSString *s ; NSString *authStr ; s = [NSString stringWithFormat:@"%@:%@",user,password] ; s = [YourBase64Encoder base64EncodingForData:[NSData dataWithBytes:[s UTF8String] length:strlen([s UTF8String])]]; authStr = [NSString stringWithFormat:@"Basic %@",s] ; [request setValue:authStr forHTTPHeaderField:@"Authorization"] ;

No sé cómo se implementaría esto para otros métodos de autenticación, pero supongo que es posible.

2) Informar al usuario del problema y pedirle que reinicie la aplicación

3) Implemente su propio mecanismo de recuperación de http basado en sockets de bajo nivel que omita completamente a CFNetwork. Buena suerte con eso:>)


Estaba enfrentando el mismo problema, ahora funciona.

El uso de NSURLConnection puede solucionarse fácilmente agregando un número aleatorio al final de la URL:

Por lo tanto, busque su URLRequest y agregue el número aleatorio a URLRequest

NSInteger randomNumber = arc4random() % 999; NSString *requestURL = [NSString stringWithFormat:@"%@?cache=%ld",yourURL,(long)randomNumber]; NSURL *URLRequest = [NSURL URLWithString:requestURL];

Y asegúrese de tener un número aleatorio al final de todas las URL que está llamando.


Por lo que vale, estoy teniendo el mismo problema.

Creo que es un problema de tiempo. Al usar el simulador, si espero entre 5 y 10 segundos antes de intentar iniciar sesión nuevamente, el inicio de sesión falla como se esperaba. Además, cuando uso un teléfono real, rara vez puedo solucionar el problema, lo que podría deberse a que el teléfono sea más lento o podría ser un error en el simulador.


Sé que es un viejo tema. Sin embargo, lo único que me funcionó fue utilizar diferentes URL para diferentes certificados.

Funcionó en mi aplicación, ya que solo tengo 2 certificados (uno general en recursos de la aplicación y otro personalizado descargado de Internet después del proceso de verificación del usuario). En mi caso, no hay cookies ni credenciales que borrar, por lo que ninguna de las soluciones que encontré en funcionó.


También me he encontrado con este problema. La NSURLCredentialStorage parece funcionar parcialmente, pero parece que tengo que esperar unos segundos después de esto para que surta efecto. Hacer otra solicitud HTTP sin esperar los resultados en el encabezado de autorización anterior que se está utilizando.

Pude solucionarlo al pasar NSURLCredentialPersistenceNone al inicializar mi NSURLCredential :

NSURLCredential* credentials = [[NSURLCredential alloc] initWithUser:username password:password persistence:NSURLCredentialPersistenceNone];

nota: esto causará 401 desafíos en cada solicitud HTTP que realice con esta NSURLCredential . Sin embargo, esto no es un problema si recupera algunas cookies que lo mantienen autenticado.