403错误 – 这是一个错误。 错误:disallowed_useragent
我正在尝试在iOS应用程序内授权用户使用Google日历API。 我正在使用Google的OAuth2function对用户进行身份validation。 授权页面打开,出现403错误的描述:
此用户代理不被允许向Google发出OAuth授权请求,因为它被归类为embedded式用户代理(也称为networking视图)。 根据我们的政策,只有浏览器可以向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";
简而言之,Google已经更新了OAuthstream程的安全限制。 他们不会允许本地networking浏览器启动OAuthstream程,而是鼓励人们使用操作系统浏览器来做到这一点。 在你的情况下,你可能不得不等待Google日历SDK更新他们的代码来遵守新推荐的stream程。 更多信息可在Google博客中find
编辑:我试图创build一个跨平台的插件,在Xamarin表单应用程序中使用本地谷歌loginSDK包装。 更多信息可以在这里find
在我的情况下,我使用本地networking视图与谷歌login,我find了方法,你应该提供用户代理到web视图它为我工作。 尝试下面的代码,我相信它会工作。
目标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)
<preference name="OverrideUserAgent" value="Mozilla/5.0 Google" />
我也在cordova项目上面对这个问题。 你可以试试这个:把这个添加到你的config.xml中,为我工作。
正如在前面的答案中所提到的, SFSafariViewController
是一种方法,但对于那些仍然使用WKWebView
进行OAuth授权的人来说,有一个简单的解决方法。
只需将customUserAgent
更改为列表中的任一个,或将其设置为任意值即可。 之后, 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"; }
要更改UIWebView
User-Agent
,您可以检查这个答案 。
但要小心,因为一些后端代码可以依赖于User-Agent
头部值。
默认情况下,如果您没有任何Google应用程序,那么当我们使用以下方法启动login时,Google SDK会在UIWebView
内部打开login。
[[GIDSignIn sharedInstance] signIn];
在这之前我刚刚添加了一行,如下所示。
[[GIDSignIn sharedInstance] setAllowsSignInWithWebView:NO];
现在谷歌不授权使用UIWebView
popup窗口。 而是在Safari浏览器中打开。 现在一切都按照原来的方式工作。
看看这个问题。 改用GTMAppAuth。
Google决定不再允许embedded式浏览器处理oAuthauthentication。 最好的方法是在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
和Swift:
// 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 }
有关此问题的完整博客文章可在此处find: 解决Google服务的“disallowed_useragent”问题
Google OAuth政策最近的变化之后,针对这个问题有一个解决方法。
在集成Google Sign和启用Google Calendar API之后,我可以使用Google Calendar API来获取和添加日历事件。 我们只需要设置GTLServiceCalendar的授权者,它是在Googlelogin后获得的。
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开发者控制台中的显示方式。
在Googlelogin完成login后,使用currentUser
来获取fetcherAuthorizer
,这可以像Google Drive服务的授权人一样使用。
之后,您可以正常使用Google云端硬盘服务 :
GIDGoogleUser *googleUser = [GIDSignIn sharedInstance].currentUser; if(googleUser != nil){ self.service.authorizer = googleUser.authentication.fetcherAuthorizer; [self listFiles]; }