如何防止在使用Google OAuth 2.0时显示访问代码的额外视图

我遵循http://googlemac.blogspot.com/2011/05/ios-and-mac-sign-in-controllers.html允许用户使用Googlelogin到iPhone应用程序。 当我点击“允许访问”button后,我得到一个额外的屏幕,说: “请复制这个代码,切换到您的应用程序,并粘贴在那里:(代码在文本框中)。

这是我的:

- (IBAction)googleLoginTapped:(UIButton *)sender { [self loginToGoogle]; } - (void)loginToGoogle { // For Google APIs, the scope strings are available // in the service constant header files. NSString *scope =@"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 

请看这个链接是否正确https://developers.google.com/accounts/docs/OAuth2InstalledApp

我试过这种方法,工作正常,把这个在你的webViewDidFinishLoad方法:

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

我find了答案。 最初,我使用已安装的应用程序的客户端ID。 这没有给出设置redirectURI的选项。 它提供了urn:uiet:wg:oauth:2.0:oob http:// localhost的默认redirectURI 所以当我用这个代码发送一个authentication请求时:

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

它返回了一个成功的代码,然后用来授权原生应用程序。 有关返回的代码或令牌的更多信息,请参阅此处 。

为了解决我的问题,我继续使用Web应用程序的客户端ID。 这允许我明确地设置redirectURI,并且还允许我在这里设置response_type来代替代码:

 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** 

所以,当我通过身份validation,并从服务器返回redirect_uri时,它会附带一个“access_tocken”作为查询string,如下所示:

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

现在您可以使用正则expression式代码:

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

拔取access_code并将其用于您的授权请求:

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

然后,您可以发送您的请求,并在这种情况下返回用户的JSON格式的configuration文件信息。 你可以参考这个问题,并回答使用Facebook的graphicsAPI来login用户。 然后修改代码,使用我在这里提供的build议和请求URL来使用新的Google OAuth 2.0。 只是在为Facebook转换代码的时候为你加速的build议,创build一个像这样的新的init方法:

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

这样你就可以轻松地使用Googlelogin对话框中的委托方法。 如果您仔细地关注Facebook示例,您应该使用OAuth进行Googlelogin,效果非常好!

事实certificate,这是非常简单的。 在logincallback中,只需closures并从父视图控制器中删除viewController

 - (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 ... } } 

我通过在UINavigationController嵌套视图控制器来解决这个问题。 不知道为什么这样做的伎俩,但它确实。

所以,而不是

 [self presentModalViewController:viewController animated:YES]; 

… 使用

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

使用gtm-oauth2loginGoogle服务时,请确保Google API Console项目注册显示在“API访问”部分中,表示已为已安装的应用程序颁发客户端ID。 这在gtm-oauth2 文档中有描述。

同时创build客户端ID,selectWeb应用程序而不是已安装的应用程序,这将解决您的问题。

快乐编码:)

我试过这个技巧,它得到了工作…

GTMOAuth2ViewControllerTouch.h中用下面的方法replacewebview的shouldStartLoadWithRequest 。 它不会显示validation码页面。

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

在此我通过检查此批准urlhttps://accounts.google.com/o/oauth2/approval?将我自己的自定义视图(redirectView)添加到此validation页面https://accounts.google.com/o/oauth2/approval?

你还应该在GTMOAuth2ViewControllerTouch的xib中添加activityView来显示加载器,同时redirect回应用程序。

经过至less20个小时的configuration,我终于得到了这个运行。 我以前也将我的swift文件导入到我的GTMOAuth2ViewControllerTouch.m文件中。 不知道这是否影响,但我补充说:

  #import "myBundleId-Swift.h" 

然后,在viewController.swift文件中,我需要添加最后2行:

  // 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() } } 

这摆脱了复制这个代码屏幕。