2011-09-26 7 views
11

Seguí http://googlemac.blogspot.com/2011/05/ios-and-mac-sign-in-controllers.html para permitir a los usuarios usar Google para iniciar sesión en una aplicación de iPhone. Después de tocar el botón "Permitir acceso" obtengo una pantalla adicional que dice, "Copie este código, cambie a su aplicación y péguelo allí: (código en un cuadro de texto)".Cómo evitar que la vista adicional muestre un código de acceso al utilizar Google OAuth 2.0

Esto es lo que tengo:

- (IBAction)googleLoginTapped:(UIButton *)sender 
{ 
    [self loginToGoogle]; 
} 

- (void)loginToGoogle 
{ 

    // For Google APIs, the scope strings are available 
    // in the service constant header files. 
    NSString *scope [email protected]"https://www.googleapis.com/auth/userinfo.profile"; 

    // Typically, applications will hardcode the client ID and client secret 
    // strings into the source code; they should not be user-editable or visible. 

    // But for this sample code, they are editable. 
    NSString *clientID = @"my clientID"; 
    NSString *clientSecret = @"my clientSecret"; 


    // Display the autentication view. 
    SEL finishedSel = @selector(viewController:finishedWithAuth:error:); 

    GTMOAuth2ViewControllerTouch *viewController; 

    viewController = [GTMOAuth2ViewControllerTouch controllerWithScope:scope 
                   clientID:clientID 
                  clientSecret:clientSecret 
                 keychainItemName:nil 
                   delegate:self 
                 finishedSelector:finishedSel]; 

    // For this sample, we'll force English as the display language. 
    NSDictionary *params = [NSDictionary dictionaryWithObject:@"en" 
                 forKey:@"hl"]; 

    viewController.signIn.additionalAuthorizationParameters = params; 

    // Optional: display some html briefly before the sign-in page loads 
    NSString *html = @"<html><body bgcolor=silver><div align=center>Loading sign-in page...</div></body></html>"; 
    viewController.initialHTMLString = html; 

    viewController.signIn.shouldFetchGoogleUserProfile = YES; 

    [self presentModalViewController:viewController animated:YES]; 
} 

- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error 
{ 
    if (error != nil) 
    { 
     // Authentication failed (perhaps the user denied 

favor ver este enlace es de buena https://developers.google.com/accounts/docs/OAuth2InstalledApp

+0

@kevlar tiene la respuesta correcta – 2cupsOfTech

Respuesta

0

Al usar GTM-OAuth2 para acceder a los servicios de Google, asegúrese de que los programas de registro Google API Console proyecto en la sección Acceso a API que se emite el ID de cliente para una aplicación instalada. Esto se describe en gtm-oauth2 documentation.

6

He encontrado la respuesta. Inicialmente estaba usando la ID de cliente para una aplicación instalada. Esto no dio la opción de configurar el URI de redireccionamiento. Dio un URI de redireccionamiento predeterminado de urn: ietf: wg: oauth: 2.0: oob http://localhost. Así que cuando me envió una solicitud de autenticación que utiliza este código:

viewController = [GTMOAuth2ViewControllerTouch controllerWithScope:scope 
                   clientID:clientID 
                  clientSecret:clientSecret 
                 keychainItemName:nil 
                   delegate:self 
                 finishedSelector:finishedSel]; 

Se ha devuelto un código de éxito que se utiliza a continuación para autorizar las aplicaciones nativas. Por favor refiera here para más información sobre los códigos o tokens devueltos.

Para solucionar mi problema, utilicé una ID de cliente para la aplicación web. Esto me permitió establecer explícitamente un URI de redireccionamiento y también permitió que fije el response_type Token en lugar de código aquí:

https://accounts.google.com/o/oauth2/auth? 
    client_id=21302922996.apps.googleusercontent.com& 
    redirect_uri=https://www.example.com/back& 
    scope=https://www.google.com/m8/feeds/& 
    response_type=**token** 

Así que cuando estoy autenticado y redirect_uri se sirve desde el servidor viene con un " access_tocken" añadido como una cadena de consulta como esta:

https://www.example.com/back?access_token=returned_access_tocken 

Ahora puede utilizar un código de expresión regular:

-(void)checkForAccessToken:(NSString *)urlString { 
    NSError *error; 
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"access_token=(.*)&" options:0 error:&error]; 
    if (regex != nil) 
    { 
     NSTextCheckingResult *firstMatch = [regex firstMatchInString:urlString options:0 range:NSMakeRange(0, [urlString length])]; 
     if (firstMatch) 
     { 
      NSRange accessTokenRange = [firstMatch rangeAtIndex:1]; 
      NSString *accessToken = [urlString substringWithRange:accessTokenRange]; 
      accessToken = [accessToken stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
      [_delegate accessTokenFoundGoogle:accessToken]; 
      accessTokenFound = YES; 
     } 
    } 
} 

para arrancar el access_code y utilizarlo para y nuestra solicitud de autorización aquí:

"https://www.googleapis.com/oauth2/v1/userinfo?oauth_token=put_your_accesstoken_here" to send a request for authorization 

a continuación, puedes enviar su solicitud y se pondrá en este caso, la información del perfil del usuario en formato JSON. Puede consultar este question and answer para utilizar la API de gráficos de Facebook para iniciar sesión. Luego, simplemente modifique el código para que funcione con el nuevo Google OAuth 2.0 usando las sugerencias y URL de solicitud que he incluido aquí. Sólo una sugerencia para acelerar las cosas para que al convertir el código para Facebook, crear un nuevo método init así:

- (id)initWithDelegate:(id<GoogleLoginDialogDelegate>)delegate; 

- (id)initWithDelegate:(id<GoogleLoginDialogDelegate>)delegate 
{ 
    if ((self = [super initWithNibName:@"GoogleLoginDialog" bundle:[NSBundle mainBundle]])) { 
     self.delegate = delegate; 
    } 
    return self;  
} 

Así que se puede trabajar con los métodos fácilemte delegado de su cuadro de diálogo de acceso a Google. Si sigues cuidadosamente el ejemplo de Facebook, ¡deberías tener el inicio de sesión de Google con OAuth funcionando muy bien!

+0

Cómo usamos esto muéstrame 400. Eso es un error. Error: invalid_request Falta el parámetro requerido: response_type –

5

Resulta que esto es bastante sencillo. En la devolución de llamada de inicio de sesión, simplemente descarte y elimine viewController del controlador de vista principal.

- (void)viewController:(UIViewController *)viewController 
     finishedWithAuth:(GTMOAuth2Authentication *)auth 
       error:(NSError *)error 
{ 
    if (error == nil) { 
     // Get rid of the login view. 
     // self.parentViewController was saved somewhere else and is the parent 
     // view controller of the view controller that shows the google login view. 
     [self.parentViewController dismissViewControllerAnimated:NO completion:nil]; 
     [viewController removeFromParentViewController]; 

     // Tell the delegate that the user successfully logged in ... 
    } else { 
     // Error handling code ... 
    } 
} 
+1

Esto no funciona para mí-- aparece el mensaje "Copie este código," antes de * la llamada a viewController: finishedWithAuth: error: en mi caso. –

+0

Funciona para mí en iPhone, iOS 9.2.1 (Swift). Sin embargo, no es perfecto. El usuario aún puede ver brevemente la pantalla "Copie este código ...". Seguiré buscando una solución aún mejor. – marco

1

i fijo esta anidando el controlador de vista interior de una UINavigationController. Ni idea de por qué hizo eso el truco, pero lo hizo.

Así que en lugar de

[self presentModalViewController:viewController animated:YES]; 

... usar

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; 
[self presentModalViewController:navigationController animated:YES]; 
+0

Esto no funciona para mí. –

9

Probé este enfoque, y funcionan bien, poner esto en su método de webViewDidFinishLoad:

if ([webView.request.URL.absoluteString rangeOfString:@"https://accounts.google.com/o/oauth2/approval?"].location != NSNotFound) { 
    webView.hidden=YES; 
} 
+1

Para aclarar: debe copiar y pegar las líneas anteriores en el archivo GTMOAuth2ViewControllerTouch.m en la sección OAuth2 de la biblioteca del cliente de Google API Objective C. Es un truco, pero funcionó para mí. – Jono

+1

Gracias! Esta es la única solución que funcionó para mí. – Jesse

+2

Hice lo mismo, pero no puedo ocultar la vista web. Todavía se ve incluso después de que lo oculté según la condición anterior. También puse breakpoint para estar seguro. – NSPratik

0

mientras que la creación ID de cliente: elija Aplicación web en lugar de la aplicación instalada, esto resolverá su problema.

feliz de codificación :)

0

yo probamos este truco y se pone el trabajo ...

reemplazar la vista web shouldStartLoadWithRequest con este método más adelante en GTMOAuth2ViewControllerTouch.h. No mostrará la página de códigos de autenticación.

*- (BOOL)webView:(UIWebView *)webView 
    shouldStartLoadWithRequest:(NSURLRequest *)request 
       navigationType:(UIWebViewNavigationType)navigationType { 
    if (!hasDoneFinalRedirect_) 
    { 
     hasDoneFinalRedirect_ = [signIn_ requestRedirectedToRequest:request]; 

     if ([request.URL.absoluteString rangeOfString:@"https://accounts.google.com/o/oauth2/approval?"].location != NSNotFound) 
     { 
      self.redirectView.frame=[UIScreen mainScreen].bounds; 
      //webView.frame=[UIScreen mainScreen].bounds; 
      [self.activityView startAnimating]; 
      [webView addSubview:self.redirectView]; 

      return YES; 
     } 
     else if(hasDoneFinalRedirect_) { 
      // signIn has told the view to close 
      return NO; 
     } 
    } 

    return YES; 
}* 

en este añado mi propia vista personalizada (RedirectView) a esta página de autenticación mediante la comprobación de esta aprobación url https://accounts.google.com/o/oauth2/approval?

y También debe agregar activityView en xib de GTMOAuth2ViewControllerTouch para mostrar el cargador, mientras que los usuarios sean redirigidos a la aplicación.

0

Después de al menos 20 horas de configuración, finalmente lo conseguí. También importé previamente mi archivo rápido en mi archivo GTMOAuth2ViewControllerTouch.m. No estoy seguro si lo que impactó pero ha añadido:

#import "myBundleId-Swift.h" 

A continuación, en el archivo viewController.swift que necesitaba para añadir los últimos 2 líneas:

// Handle completion of the authorization process, and updates the Drive service 
// with the new credentials. 
func viewController(viewController: GTMOAuth2ViewControllerTouch , finishedWithAuth authResult: GTMOAuth2Authentication, error:NSError?) { 
    if let error = error 
    { 
     self.showAlert("Authentication Error", message:error.localizedDescription) 
     self.driveService.authorizer = nil 
    } else { 
     print("Authentication success") 
     self.driveService.authorizer = authResult 
//This where we need to get rid of the copy the code screen: 
     self.parentViewController?.dismissViewControllerAnimated(false, completion:nil) 
     viewController.removeFromParentViewController() 
    } 
} 

que se libró de la copia de esta pantalla de código .

Cuestiones relacionadas