403错误 - 这是一个错误。错误:disallowed_useragent

时间:2016-11-14 14:29:43

标签: ios iphone google-calendar-api google-oauth

我正在尝试在IOS应用中授权用户使用Google日历API。 我正在使用Google的OAuth2功能对用户进行身份验证。将打开授权页面,其中包含描述为403的错误:

  

此用户代理不允许向Google发出OAuth授权请求,因为它被归类为嵌入式用户代理(也称为Web视图)。根据我们的政策,只允许浏览器向Google发出授权请求。我们为本机应用程序提供了几个库和示例,以便在浏览器中执行授权请求。

我遵循了此链接中提到的相同程序:https://developers.google.com/google-apps/calendar/quickstart/ios

不要查看我的代码,最好查看此链接:https://developers.google.com/google-apps/calendar/quickstart/ios 因为我在我的申请中复制粘贴了同样的东西。

下面的

是我的clientId和keyChainItemName:

static NSString *const kKeychainItemName = @"Google Calendar API";
static NSString *const kClientID = @"954370342601-sgl8k0jrbqdeagea9v6vfu3tspte96ci.apps.googleusercontent.com";

13 个答案:

答案 0 :(得分:28)

在我的情况下,我使用本机网络视图登录谷歌,我发现你应该为webview提供用户代理的方式它是为我工作的。尝试以下代码我相信它会起作用。

应用程序中添加代码didFinishLaunchingWithOptions

目标C

 NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36", @"UserAgent", nil];
 [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];

Swift 3.0

let dictionaty = NSDictionary(object: "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36", forKey: "UserAgent" as NSCopying)
UserDefaults.standard.register(defaults: dictionaty)

答案 1 :(得分:14)

<preference name="OverrideUserAgent" value="Mozilla/5.0 Google" />

我的cordova项目也面临这个问题。你可以试试这个: 只需将此添加到您的config.xml,为我工作。

答案 2 :(得分:13)

简短的回答是Google已更新其对OAuth流量的安全限制。他们不会允许原生网络视图启动OAuth流程,而是鼓励人们使用操作系统浏览器这样做。在您的情况下,您可能需要等待Google日历SDK更新其代码以遵守新推荐的流程。有关详细信息,请参阅Google blog

编辑:我试图创建一个跨平台插件,它包含本机Google登录SDK,以便在Xamarin表单应用程序中使用。可以找到更多信息here

答案 3 :(得分:8)

正如之前的回答所述,SFSafariViewController是一种可行的方法,但对于仍然使用WKWebView进行OAuth授权的用户,有一个简单的解决方法。

只需将customUserAgent更改为list中的任意一个,或将其设置为某个任意值。之后disallowed_useragent错误将消失:

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
// Check for selector availability, as it is available only on iOS 9+
if ([webView respondsToSelector:@selector(setCustomUserAgent:)]) {
    webView.customUserAgent = @"MyCustomUserAgent";
}

要更改User-Agent中的UIWebView,您可以查看this answer

但请注意,因为某些后端代码可能依赖于User-Agent标头值。

答案 4 :(得分:5)

同样的问题。通过将以下属性设置为webview对象来已解决

webview.getSettings().setUserAgentString("Chrome/56.0.0.0 Mobile");

希望这会有所帮助。

答案 5 :(得分:3)

默认情况下,如果您没有任何Google应用,那么当我们使用以下方法启动登录时,Google SDK会在UIWebView内打开登录信息。

        [[GIDSignIn sharedInstance] signIn];

我刚刚在此之前添加了一行,如下所示。

        [[GIDSignIn sharedInstance] setAllowsSignInWithWebView:NO];

现在谷歌没有使用UIWebView弹出窗口进行授权。相反,它会在Safari浏览器中打开。现在一切都按原样运作。

答案 6 :(得分:2)

请查看this issue.改为使用GTMAppAuth。

答案 7 :(得分:2)

Google决定不再允许嵌入式浏览器处理oAuth身份验证。最好的方法是在iOS上使用SFSafariViewController。以下是使用CloudRail SDK解决的问题:

在Objective-C中:

@implementation AppDelegate

  // This method will receive the redirect URI after the authentication process was
  // successfull
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {

  // Here we pass the response to the SDK which will automatically
  // complete the authentication process.
  [[NSNotificationCenter defaultCenter] postNotificationName:@"kCloseSafariViewControllerNotification" object:url];

  return YES;
}

@end

和斯威夫特:

// This method will receive the redirect URI after the authentication process was
// successfull
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {

    if (sourceApplication == "com.apple.SafariViewService") {
        // Here we pass the response to the SDK which will automatically
        // complete the authentication process.
        NSNotificationCenter.defaultCenter().postNotificationName("kCloseSafariViewControllerNotification", object: url)
        return true
    }
    return true
}

有关此问题的完整博文可在此处找到:Solving ‘disallowed_useragent’ for Google services

答案 8 :(得分:2)

最近Google OAuth政策发生变化后,此问题有解决方法。

在集成Google Sign并启用Google Calendar API后,我能够使用Google Calendar API来获取和添加日历活动。我们只需要为Google登录后获取的GTLServiceCalendar设置授权程序。

service.authorizer = user.authentication.fetcherAuthorizer()

以下是Google GIDSignIn的代码段,然后是提取日历事件。

import GoogleAPIClient
import GTMOAuth2
import UIKit
import GoogleSignIn

class ViewController: UIViewController, GIDSignInUIDelegate, GIDSignInDelegate {

  private let kApiKey = "AIzaXXXXXXXXXXXXXXXXXXXXXXX"

  // If modifying these scopes, delete your previously saved credentials by
  // resetting the iOS simulator or uninstall the app.
  private let scopes = [kGTLAuthScopeCalendar]
  private let service = GTLServiceCalendar()

  override func viewDidLoad() {
      super.viewDidLoad()

      service.apiKey = kApiKey

      GIDSignIn.sharedInstance().uiDelegate = self
      GIDSignIn.sharedInstance().scopes = scopes
      GIDSignIn.sharedInstance().signIn()
      GIDSignIn.sharedInstance().delegate = self
  }


  func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {

      if user != nil {
           print("\(user)")
           service.authorizer = user.authentication.fetcherAuthorizer()
           fetchEvents()
      }
  }

 // Construct a query and get a list of upcoming events from the user calendar
   func fetchEvents() {

        let query = GTLQueryCalendar.queryForEventsList(withCalendarId: "primary")
        query?.maxResults = 20
        query?.singleEvents = true
        query?.orderBy = kGTLCalendarOrderByStartTime

        service.executeQuery(query!, delegate: self, didFinish: #selector(ViewController.displayResultWithTicket(ticket:finishedWithObject:error:)))
   }

// Display the start dates and event summaries in the UITextView
    func displayResultWithTicket(
         ticket: GTLServiceTicket,
        finishedWithObject response : GTLCalendarEvents,
        error : NSError?) {

        if let error = error {
            showAlert(title: "Error", message: error.localizedDescription)
            return
        }

        var eventString = ""

        if let events = response.items(), !events.isEmpty {
            for event in events as! [GTLCalendarEvent] {
                print(event)
             }
        } else
                print("No upcoming events found.")
        }
    }

    }

这是我的凭据部分在Google开发者控制台中的显示方式。

enter image description here

答案 9 :(得分:1)

Google登录完成登录后,使用currentUser获取fetcherAuthorizer,这可以像 Google云端硬盘服务的授权者一样使用。< / p>

之后,您可以正常使用 Google云端硬盘服务

GIDGoogleUser *googleUser = [GIDSignIn sharedInstance].currentUser;

if(googleUser != nil){
    self.service.authorizer = googleUser.authentication.fetcherAuthorizer;
    [self listFiles];

}

答案 10 :(得分:1)

这对我有用

mWebView.getSettings().setUserAgentString("Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19");

答案 11 :(得分:0)

我解决了花了1年的时间:-)开玩笑。 只需在config.xml中优先添加以下行

<preference name="OverrideUserAgent" value="Mozilla/5.0 Google" />

请注意,我使用Inapp浏览器解决了此Google登录问题。

谢谢

答案 12 :(得分:-1)

我在 Google Signin InAppBrowser 上收到错误:“403 错误 - 那是一个错误。错误:disallowed_useragent”,对于我的情况,修复程序是添加这样的 userAgent 属性在网络视图中:

 <WebView
 // other props here
  userAgent={"Chrome/56.0.0.0 Mobile"}
 />