403 Error - Thats an error. Error: disallowed_useragent
Asked Answered
S

15

55

I am trying to authorise a user for Google calendar API inside an IOS app. I am using the OAuth2 feature of Google to authenticate users. Authorisation page opens with a 403 error with the description:

This user-agent is not permitted to make OAuth authorisation request to Google as it is classified as an embedded user-agent (also known as a web-view). Per our policy, only browsers are permitted to make authorisation requests to Google. We offer several libraries and samples for native apps to perform authorisation request in browser.

I followed the same procedure which is mentioned in this link: https://developers.google.com/google-apps/calendar/quickstart/ios

Rather than seeing my code, it's better to look at this link: https://developers.google.com/google-apps/calendar/quickstart/ios because I copy-pasted the same thing in my application.

below are my clientId and keyChainItemName:

static NSString *const kKeychainItemName = @"Google Calendar API";
static NSString *const kClientID = @"954370342601-sgl8k0jrbqdeagea9v6vfu3tspte96ci.apps.googleusercontent.com";
Same answered 14/11, 2016 at 14:29 Comment(5)
Show your source codeProduct
What approach did you go with?Unexpressed
@Subbhu Did you get any solution for this?Breadwinner
I faced this error in Android. I solved by setting "User Agent" for local WebView settings i.e. String ua = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"; webview.getSettings().setUserAgentString(ua); You can find more in respect of IOS here: forums.xamarin.com/discussion/86415/…Paucker
this policy sucks, we have an established webview based OAuth approach (multi-platform with server side control) for various third party apps. And we're supposed to put in some special browser flow for Google apps? Using a webview allows us to do certificate pinning with our server communication + it gives us more control to strip sensitive info from headers + we need to facilitate login to multiple accounts for the same third party app (not all third party APIs allow you to force prompt to login and so sometimes it is essential to clear the cookies using webview approach).Shew
B
36

In my case I was using native web view to login with Google, I find out the way that you should provide user agent to webview it was worked for me. Try below code I am sure it will worked.

Add the code in application didFinishLaunchingWithOptions

Objective 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

UserDefaults.standard.register(defaults: ["UserAgent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"])
Britisher answered 7/4, 2017 at 5:59 Comment(3)
Just to clarify the Objective C solution. Add this code to: (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {}Siltstone
Still gives out the same error. Anyone else who is still facing the same?Hintz
Worked well for me. You can use newer UserAgent by finding one here developers.whatismybrowser.com/useragents/explore/software_name/… and c/p stringOhaus
D
17

The short answer is that Google has updated its security restrictions for OAuth flow. They are not going to allow native web-views to initiate OAuth flows, but rather are encouraging people to use the OS browsers to do so. In your case, you'll probably have to wait for the Google calendar SDK to update their code to obey the newly recommended flow. More information is available in the Google blog

EDIT : I have tried to create a cross platform plugin which wraps around the native Google sign-in SDKs for using in a Xamarin forms app. More information can be found here

Deliadelian answered 15/11, 2016 at 8:35 Comment(4)
Thanks a lot @Rhishkeshj but it does not give solution for this issue. I want to know any other alternatives available.. still i am seeking for AnswersSame
Issue was logged for drive as well code.google.com/a/google.com/p/apps-api-issues/issues/…Pianism
@Same Unfortunately there is no easy solution around this right now. The thing that I did was to use the native Google sign in SDKs and integrate them separately into the iOS and Droid projects. Seems to be working fairly well, although the usage from a PCL is currently very limited for that. I am trying to develop this setup into a standalone plugin. So lets see.Deliadelian
Incredibly, this problem also happens with the native browsers from Android 4.x from the pre-Chrome monopoly and updateable webview-era.Sericin
D
17
<preference name="OverrideUserAgent" value="Mozilla/5.0 Google" />

I also face this issue on my cordova project. You can try this: Just add this to your config.xml, worked for me.

Dragging answered 21/4, 2017 at 11:0 Comment(5)
sorry for that . my code not shown properly before now i correct it . you can try it now. <preference name="OverrideUserAgent" value"Mozilla/5.0 Google" />Dragging
same issue i am facing in android , can you suggest me how can i fix this.Sianna
Can you please explain me which platform you use for create android app. Like cordova , ionic or native android apps in Android studio.Dragging
native android app in Android studioSianna
For people using capacitor, update your capacitor.config.json with "overrideUserAgent": "Mozilla/5.0 Google"Likeness
B
13

Got same issue. Resolved by setting following property to the webview object:

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

Hope this will help.

Buskirk answered 12/12, 2017 at 5:32 Comment(1)
"Chrome/124.0.0.0 Mobile" works for meMarylouisemaryly
G
8

As mentioned in previous answers, SFSafariViewController is a way to go, but for those who still uses WKWebView for OAuth authorization there is a simple workaround.

Just change customUserAgent to either one from list or set it to some arbitrary value. After that disallowed_useragent error will disappear:

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";
}

For changing User-Agent in UIWebView you can check this answer.

But be careful, as some backend code can depend on User-Agent header value.

Guntar answered 22/2, 2017 at 8:57 Comment(1)
Works perfectly for me :)Raguelragweed
Y
3

By default, if you don't have any google app, the google SDK opens the login inside a UIWebView when we initiate the login by using the following method.

        [[GIDSignIn sharedInstance] signIn];

I just added one line before this, which is as follows.

        [[GIDSignIn sharedInstance] setAllowsSignInWithWebView:NO];

Now the google doesn't authorise using the UIWebView popup. Instead, it opens in the Safari browser. And now everything just works as the way it was.

Yonatan answered 11/1, 2017 at 17:12 Comment(2)
In my case that solved the issue! Thank you very much!Thunderclap
thanx you.. you save meFishnet
T
3

Google decided to not longer allow embedded browsers to handle the oAuth authentication. The best way is to use SFSafariViewController on iOS. Here is how it can be solved using the CloudRail SDK:

In 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

and 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
}

The complete blog post covering this issue can be found here: Solving ‘disallowed_useragent’ for Google services

Tobietobin answered 27/1, 2017 at 10:54 Comment(1)
Need more details please @TobietobinSolorzano
C
2

Take a look at this issue. Use GTMAppAuth instead.

Chilli answered 28/12, 2016 at 2:52 Comment(1)
GTMAppAuth is the actual solution given by Google as well. Thanks CarolynSynder
G
2

There is a workaround for this issue after the recent change in Google OAuth policies.

After integrating the Google Sign and enabling Google Calendar API, I was able to work with Google Calendar API to fetch and add Calendar Events. We just have to set the authorizer for GTLServiceCalendar which is obtained after Google sign-in.

service.authorizer = user.authentication.fetcherAuthorizer()

Here is the code snippets of Google GIDSignIn, followed by fetching calendar events.

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.")
        }
    }

    }

This is how my credentials section appear in Google Dev Console.

enter image description here

Gertudegerty answered 4/2, 2017 at 20:45 Comment(9)
hiiii could u help me with this @Jen Jose...i need to create and save eventAckler
@DilipTiwari, where are you stuck? Even Dipen 's answer works, but I personally prefer not to meddle with Safari preferences and it's better to use Google authoriser as mentioned in the error.Gertudegerty
I have followed this link developers.google.com/google-apps/calendar/quickstart/ios and successfully showing button and further process to sign in with google and when i add event in web browser with same event i m able to show that on textview in viewcontroller but i want to know how to create event and save in ios app swift @Jen JoseAckler
if u have i can talk u through skype or personal chatAckler
i integrating the Google Sign and enabling Google Calendar API correctly and it is working but how will work with Google Calendar API to fetch and add Calendar Events.need helpAckler
I tried the way you suggested, but, I am not able to fetch the events from calendar, can you please help here?Antarctic
and getting this error NSError domain: "com.google.GTLJSONRPCErrorDomain" - code: 401 0x000060000045d130Antarctic
Can you please check this issue getting while fetching events from google calendar #51299436 @JenJoseAntarctic
THANK YOU SOOOOO MUCH BROTHER!Maggoty
F
1

After the google sign-in finishes the login, use the currentUser to get the fetcherAuthorizer, this can be used like an authorizer for the Google Drive Service.

After that you can use the Google Drive Service normally:

GIDGoogleUser *googleUser = [GIDSignIn sharedInstance].currentUser;

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

}
Feme answered 15/3, 2017 at 18:11 Comment(0)
P
1

This is working for me

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");
Peipus answered 14/8, 2019 at 5:37 Comment(0)
A
0

Error 403: disallowed_useragent

Few days ago facing same issue, thought to post here. I was trying to login with Google.

enter image description here

Browser is not compatible with the device. When you open web-view need to add few lines for code in order to work. Steps

  1. In Web-view declare string variable called userAgent and While loading request use this customUserAgent property assign userAgent to it.
let userAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36 Mozilla/5.0(iPad; U;CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10(KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10"
  if let url = URL(string: mandateUrl){
     let request = URLRequest(url: url)
     webView.customUserAgent = userAgent
     webView.load(request)  
}
Artamas answered 30/8, 2022 at 7:22 Comment(0)
B
0

Error 403: disallowed_useragent You can’t sign in from this screen because this app doesn’t comply with Google’s secure browsers policy. If this app has a website, you can open a web browser and try signing in from there.

You can let the app developer know that this app doesn’t comply with Google’s secure browsers policy. Learn more Request Details HelpPrivacyTerms

Bonedry answered 16/10, 2022 at 14:41 Comment(0)
H
-1

I solved the issue it took 1 year :-) just kidding. just add the below line in preference in config.xml

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

Please note i solved this google login issue with Inapp browser.

Thanks

Humboldt answered 27/2, 2019 at 12:48 Comment(0)
E
-1

I was getting error: "403 Error - Thats an error. Error: disallowed_useragent" on Google Signin InAppBrowser and for my situation the fix was adding userAgent property like this in Webview:

 <WebView
 // other props here
  userAgent={"Chrome/56.0.0.0 Mobile"}
 />
Encomiast answered 28/1, 2021 at 11:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.