我正在尝试在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";
答案 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开发者控制台中的显示方式。
答案 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"}
/>