IOSアプリ内で、GoogleカレンダーAPIのユーザーを認証しようとしています。 GoogleのOAuth2機能を使ってユーザーを認証しています。認証ページが開くと、403エラーが発生し、次のような説明が表示されます:
このユーザーエージェントは、埋め込み型ユーザーエージェント(ウェブビューとも呼ばれる)に分類されるため、GoogleにOAuth認証リクエストを行うことは許可されていません。Google のポリシーでは、Google への認証リクエストはブラウザのみ許可されています。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";
私の場合、ネイティブWebビューを使用してgoogleでログインしていましたが、ユーザーエージェントにwebviewを提供する方法を見つけました。 以下のコードを試してみてください。
application 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];
スウィフト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" />
私のコルドバプロジェクトでもこの問題に直面しています。 あなたはこれを試すことができます: これをconfig.xmlに追加するだけで、私のために働いた。
簡単に言うと、GoogleがOAuthフローに関するセキュリティ制限を更新したということです。彼らは、ネイティブのウェブビューがOAuthフローを開始することを許可するつもりはなく、むしろ、OSブラウザを使用してそれを行うことを奨励しています。あなたの場合、GoogleカレンダーSDKが新たに推奨されるフローに従うようにコードを更新するのを待つ必要がありそうです。より詳細な情報は、Googleブログに掲載されています。
EDIT : Xamarinフォームアプリで使用するために、ネイティブのGoogleサインインSDKをラップするクロスプラットフォームプラグインを作成しようと試みました。詳細はこちらを参照してください。
以前の回答で述べたように、「SFSafariViewController」は進むべき道ですが、OAuthの承認に「WKWebView」をまだ使用している人にとっては、簡単な回避策があります。
listから customUserAgent
をどちらかに変更するだけです?typ = Browser)または任意の値に設定します。 その後、「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
を変更するには、この回答を確認できます。
ただし、一部のバックエンドコードは「ユーザーエージェント」ヘッダー値に依存する可能性があるため、注意してください。
同じ問題が発生しました。 解決済み次のプロパティをwebviewオブジェクトに設定します。
<。!-言語:java-->。
webview.getSettings().setUserAgentString("Chrome/56.0.0.0 Mobile");
これが役立つことを願っています。
デフォルトでは、googleアプリがない場合、以下のメソッドでログインを開始すると、google SDKはUIWebView
内にログインを開く。
[[GIDSignIn sharedInstance] signIn];
この前に1行追加しただけで、次のようになります。
[[GIDSignIn sharedInstance] setAllowsSignInWithWebView:NO];
今、googleはUIWebView
ポップアップを使用することを許可していません。その代わり、Safariブラウザで開きます。そして今、すべてが以前と同じように動作しています。
Google OAuthポリシーの最近の変更後、この問題の回避策があります。
Googleサインを統合してGoogleカレンダーAPIを有効にした後、Googleカレンダー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 Dev Consoleに表示される方法です。
。。
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
と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
}
この問題をカバーする完全なブログ投稿は、次の場所にあります。Googleサービスの「disallowed_useragent」の解決。
グーグルサインインがログインを完了したら、「currentUser」を使用して「fetcherAuthorizer」を取得します。これは、 Googleドライブサービスのオーサライザーのように使用できます。
その後、通常 Googleドライブサービスを使用できます。
GIDGoogleUser *googleUser = [GIDSignIn sharedInstance].currentUser;
if(googleUser != nil){
self.service.authorizer = googleUser.authentication.fetcherAuthorizer;
[self listFiles];
}