我关注http://googlemac.blogspot.com/2011/05/ios-and-mac-sign-in-controllers.html以允许用户使用Google登录iPhone应用。点击“允许访问”按钮后,我会看到一个额外的屏幕,“请复制此代码,切换到您的应用程序并将其粘贴到那里:(文本框中的代码)。”
这就是我所拥有的:
- (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
答案 0 :(得分:9)
我试过这种方法,并且工作正常,把它放在你的webViewDidFinishLoad方法中:
if ([webView.request.URL.absoluteString rangeOfString:@"https://accounts.google.com/o/oauth2/approval?"].location != NSNotFound) {
webView.hidden=YES;
}
答案 1 :(得分:6)
我找到了答案。最初我使用客户端ID来安装应用程序。这没有提供设置重定向URI的选项。它提供了一个默认的重定向URI urn:ietf:wg:oauth:2.0:oob http://localhost。所以当我使用此代码发送身份验证请求时:
viewController = [GTMOAuth2ViewControllerTouch controllerWithScope:scope
clientID:clientID
clientSecret:clientSecret
keychainItemName:nil
delegate:self
finishedSelector:finishedSel];
它返回了一个成功代码,然后用于授权本机应用程序。有关返回的代码或令牌的更多信息,请提供here。
为解决我的问题,我继续使用客户端ID进行Web应用程序。这允许我显式设置重定向URI,并允许我在这里将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**
因此,当我通过身份验证并从服务器返回redirect_uri时,会附带一个“access_tocken”作为查询字符串,如下所示:
https://www.example.com/back?access_token=returned_access_tocken
现在您可以使用正则表达式代码:
-(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格式返回用户的个人资料信息。您可以参考此question and answer使用Facebook的图形API来登录用户。然后,只需使用我在此处提供的建议和请求网址修改代码即可使用新的Google OAuth 2.0。只是在转换Facebook代码时为您加速的建议,创建一个新的init方法,如下所示:
- (id)initWithDelegate:(id<GoogleLoginDialogDelegate>)delegate;
- (id)initWithDelegate:(id<GoogleLoginDialogDelegate>)delegate
{
if ((self = [super initWithNibName:@"GoogleLoginDialog" bundle:[NSBundle mainBundle]])) {
self.delegate = delegate;
}
return self;
}
这样您就可以轻松使用Google登录对话框中的委托方法。如果您仔细关注Facebook示例,那么您应该让Google登录OAuth工作得非常好!
答案 2 :(得分: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 ...
}
}
答案 3 :(得分:1)
我通过将视图控制器嵌套在UINavigationController
内来修复此问题。不知道为什么会这样做,但确实如此。
所以而不是
[self presentModalViewController:viewController animated:YES];
...使用
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
[self presentModalViewController:navigationController animated:YES];
答案 4 :(得分:0)
使用gtm-oauth2登录Google服务时,请确保{API}访问权限部分中的Google API Console项目注册显示为已安装的应用程序颁发了客户端ID。这在gtm-oauth2 documentation中有所描述。
答案 5 :(得分:0)
创建客户端ID时,选择Web应用程序而不是已安装的应用程序,这将解决您的问题。
快乐编码:)
答案 6 :(得分:0)
我试过这个技巧,它就可以了......
在 GTMOAuth2ViewControllerTouch.h 中使用以下方法替换webview shouldStartLoadWithRequest 。它不会显示身份验证代码页。
*- (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;
}*
在此我通过检查此审批网址https://accounts.google.com/o/oauth2/approval?
并且您还应该在GTMOAuth2ViewControllerTouch的xib中添加activityView,以在重定向回应用程序时显示加载器。
答案 7 :(得分:0)
经过至少20个小时的配置后,我终于开始运行了。我之前也将我的swift文件导入了我的GTMOAuth2ViewControllerTouch.m文件。不确定是否影响了它,但我补充道:
#import "myBundleId-Swift.h"
然后,在viewController.swift文件中,我需要添加最后两行:
// 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()
}
}
摆脱了这个代码屏幕的复制。