2011-09-26 24 views
11

私はhttp://googlemac.blogspot.com/2011/05/ios-and-mac-sign-in-controllers.htmlに続き、ユーザーはGoogleを使ってiPhoneアプリにログインできます。 「アクセスを許可」ボタンをタップした後、という追加の画面が表示されます。「このコードをコピーして、アプリケーションに切り替えて貼り付けてください(テキストボックスのコード)」Google OAuth 2.0を使用しているときにアクセスコードが表示されないようにする方法

は、これは私が持っているものです。

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

Google API Consoleプロジェクト登録ショー必ず、GoogleサービスにログインするためにGTM-のOAuth2を使用している場合、それは良いhttps://developers.google.com/accounts/docs/OAuth2InstalledApp

+0

@kevlarには正しい答えがあります – 2cupsOfTech

答えて

0

でこのリンクを参照してください。 APIアクセスセクションのにクライアントIDが発行され、アプリケーションがインストールされていることを確認します。これは、gtm-oauth2 documentationに記述されています。

6

私は答えを見つけました。最初は、インストールされたアプリケーションのクライアントIDを使用していました。これは、リダイレクトURIを設定するオプションを与えませんでした。 urn:ietf:wg:oauth:2.0:oob http://localhostの既定のリダイレクトURIを指定しました。私はこのコードを使用して認証要求を送信したときだから:

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

その後、ネイティブアプリケーションを認証するために使用されて成功コードを返しました。返されたコードやトークンの詳細については、hereを参照してください。

私の問題を解決するために、私は先に進み、Webアプリケーション用のクライアントIDを使用しました。これは私が明示的にリダイレクトURIを設定しても、私はここに代わり、コードのトークンにresponse_typeを設定することが許さすることができ:私は認証されていますし、REDIRECT_URIがサーバーから提供されたときに

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

だから "が付属していますaccess_codeを摘み取るために

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

とyのためにそれを使用します。

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

は今、あなたは正規表現コードを使用することができます:「このようなクエリ文字列として追加access_tockenここでの承認リクエスト:

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

あなたのリクエストを送信して、この場合はJSON形式のユーザーのプロフィール情報に戻すことができます。このquestion and answerを参照すると、FacebookのグラフAPIを使用してユーザーにログインできます。次に、ここに含まれている提案とリクエストURLを使用して、新しいGoogle OAuth 2.0で動作するようにコードを変更してください。あなたはイースリーにGoogleのログインダイアログからデリゲートメソッドで作業できるようにするため

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

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

:Facebookのためのコードを変換する際に、このような新しいのinitメソッドを作成し、あなたのために物事を高速化するだけの提案。 Facebookの例に注意深く従うなら、OAuthを使ったGoogleのログインはすごく効果的です!

+0

私たちはこれをどのように使用しますか400を示します。これは誤りです。 エラー:invalid_request 必要なパラメータがありません:response_type –

5

これはかなり簡単です。ログインコールバックで親ビューコントローラから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 ... 
    } 
} 
+1

これは私のためには機能しません - 「このコードをコピーしてください」というメッセージが表示される* before * viewController:finishedWithAuth:error:in my場合。 –

+0

iPhone、iOS 9.2.1(Swift)で動作します。しかしそれは完璧ではありません。ユーザーは「このコードをコピーしてください...」という画面が表示されることがあります。私はさらに良い解決策を探し続けるつもりです。 – marco

1

ビューコントローラをUINavigationControllerの中にネストすることでこれを解決しました。なぜそのトリックをしたのか分かりませんが、それはしました。

ので、代わりの

[self presentModalViewController:viewController animated:YES]; 

...私はあなたのwebViewDidFinishLoadの方法でこれを入れて、このアプローチを試みたが、うまく動作

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

これは私のためには機能しません。 –

9

を使用します。

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

明確にするには、上記の行をGoogle API Objective CクライアントライブラリのOAuth2セクションにあるGTMOAuth2ViewControllerTouch.mファイルにコピーして貼り付ける必要があります。それはハックですが、それは私のために働いた。 – Jono

+1

ありがとう!これは私のために働いた唯一の解決策です。 – Jesse

+2

私は同じことをしましたが、webviewを非表示にすることはできません。それは私がそれを上記の条件ごとに隠した後でさえまだ見られる。私はまた、ブレークポイントを置いて確実にします。 – NSPratik

0

作成中クライアントID、インストールされたアプリケーションの代わりにWebアプリケーションを選択すると、問題が解決されます。

私はこのトリックを試してみましたが、それは仕事を取得します:)

0

コーディング幸せ...

WebViewのGTMOAuth2ViewControllerTouch.hにおける方法下記これにshouldStartLoadWithRequestを交換してください。認証コードページは表示されません。私はこの承認のURLにhttps://accounts.google.com/o/oauth2/approval?

をチェックすることで、この認証ページに自分のカスタムビュー(redirectView)を追加していて、あなたはまた戻ってリダイレクトながらローダーを表示するためにGTMOAuth2ViewControllerTouchのXIBでactivityViewを追加する必要があり、この中

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

アプリケーションに転送します。

0

少なくとも20時間の設定後、私はついにこれを実行しました。私は以前に私の迅速なファイルを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() 
    } 
} 

関連する問題