Как предотвратить дополнительный просмотр, отображающий код доступа при использовании Google OAuth 2.0
Я следил за 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 [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
пожалуйста, см. эту ссылку. https://developers.google.com/accounts/docs/OAuth2InstalledApp
Ответы
Ответ 1
Я пробовал этот подход и отлично работал, поместив его в свой метод webViewDidFinishLoad:
if ([webView.request.URL.absoluteString rangeOfString:@"https://accounts.google.com/o/oauth2/approval?"].location != NSNotFound) {
webView.hidden=YES;
}
Ответ 2
Я нашел ответ. Первоначально я использовал идентификатор клиента для установленного приложения. Это не дало возможности настроить URI Redirect. Он дал URI по умолчанию для перенаправления urn: ietf: wg: oauth: 2.0: oob http://localhost. когда я отправил запрос на аутентификацию с помощью этого кода:
viewController = [GTMOAuth2ViewControllerTouch controllerWithScope:scope
clientID:clientID
clientSecret:clientSecret
keychainItemName:nil
delegate:self
finishedSelector:finishedSel];
Он вернул код успеха, который затем используется для авторизации собственных приложений. Пожалуйста, refere здесь для получения более подробной информации о возвращенных кодах или жетонах.
Чтобы исправить мою проблему, я пошел дальше и использовал идентификатор клиента для веб-приложения. Это позволило мне явно установить URI Redirect, а также разрешить мне вместо атрибута 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;
}
}
}
чтобы вырвать код доступа и использовать его для вашего запроса авторизации здесь:
"https://www.googleapis.com/oauth2/v1/userinfo?oauth_token=put_your_accesstoken_here" to send a request for authorization
Затем вы можете просто отправить свой запрос и вернуть в этом случае информацию профиля пользователя в формате JSON. Вы можете обратиться к этому вопросу и ответить для использования графического графика Facebook для входа в систему. Затем просто измените код для работы с новым 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, который отлично работает!
Ответ 3
Оказывается, это довольно просто. В обратном вызове login просто отпустите и удалите 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 ...
}
}
Ответ 4
Я исправил это, вставив контроллер представления внутри UINavigationController
. Не знаю, почему это сделал трюк, но так оно и было.
Итак, вместо
[self presentModalViewController:viewController animated:YES];
... использовать
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
[self presentModalViewController:navigationController animated:YES];
Ответ 5
При использовании gtm-oauth2 для входа в службы Google убедитесь, что Консоль API Google показывает в разделе API Access, что Идентификатор клиента выдается для приложения . Это описано в документации gtm-oauth2 .
Ответ 6
при создании идентификатора клиента, выберите веб-приложение вместо установленного приложения, это решит вашу проблему.
счастливое кодирование:)
Ответ 7
Я пробовал этот трюк, и он получает работу...
замените webview shouldStartLoadWithRequest следующим образом: GTMOAuth2ViewControllerTouch.h. Он не покажет страницу кода аутентификации.
*- (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;
}*
в этом я добавляю собственное собственное представление (redirectView) на эту страницу аутентификации, проверяя этот URL-адрес утверждения https://accounts.google.com/o/oauth2/approval?
и вы также должны добавить activityView в xib из GTMOAuth2ViewControllerTouch, чтобы показать загрузчика при перенаправлении обратно в приложение.
Ответ 8
После того, как по крайней мере 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()
}
}
Это избавило от копирования этого экрана кода.