SkyDancer
SkyDancer

Reputation: 159

Google drive OAuth2 without browser

I am trying to authenticate my login via Google drive OAuth2 in my c# desktop app. And when the user enters Client ID and Client secret, the browser opens and asks for confirmation. Also browser opens when user enters a wrong Client ID and Client secret and shows an error message on the Google web page...

So, haw can I authenticate without browser confirmation and handle all google OAuth2 errors inside my code and without any browser pages?

Here is my authentication code:

//...code
string[] scopes = new string[] { DriveService.Scope.Drive, DriveService.Scope.DriveFile };

UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
    new ClientSecrets
    {
        ClientId = "WrongID",
        ClientSecret = "WrongSecret"
    },
    scopes, _authUserName,
    CancellationToken.None, new FileDataStore(_authDataStorePath, true)).Result;
//...code

And when error occurs in this block, execution of code just stops and nothing happens.

UPDATE1:

OK, suppose that I know how to get the json file with tokens. Now, how can I make DriveService object with this file? Now I create it as follows:

DriveService _drive = new DriveService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential, // How to make this credential from tokens?
    ApplicationName = _applicationName
});

Also, how about catching Google OAuth exceptions in my c# code? Couse now the Google just show me an error info in browser and my app just hangs...

Upvotes: 4

Views: 10694

Answers (2)

Mohammad Albay
Mohammad Albay

Reputation: 309

to be able to use the same google account each time you run/install your application on a new device you have to do :

Use Google Drive Api and login to your account to grant the permissions

once you logged in, you can see a new files and a folder(called token.json) generated within the Debug/Release folder

so, to be able to use that account without opening the browser to grant permissions(repeating ), you have to keep these files and token.json folder with the executable file(your application)

Note: make sure token.json isn't empty

this method works for me,i hope this works for you as well

Upvotes: 0

referscus
referscus

Reputation: 801

ClientId and Client Secret are used to Identify your app. These need to be hard coded or pulled from a database, not input by the user. As for no browser opening for OAuth2. You can't do that anymore with API V3, and Google has deprecated all previous versions.

So you have two choices with Google Drive if you don't want to open a browser for Auth. If you want everyone who uses the app to share 1 Google drive you can set up a service account https://developers.google.com/accounts/docs/OAuth2ServiceAccount.

If everyone who uses your app will install it on their device and use their own Google drive you can set it up as an installed app with Offline/long-lived access. Google doesn't document this very well, but if you search for it there are a few good examples. You'll open the browser once to get the refresh token for that user, then store that in a database and you'll be able to access their drive every time they get on without opening a browser.

These are the only ways to do it with no browser, Google doesn't allow you to pass them a username and password anymore.

Update--

You're going to need something like this, This is for offline but online will be similar.

string path = whereYouSaveClientSecret+ "client_secret.json";
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
        StoredResponse myStoredResponse = new StoredResponse(RefreshToken);
        credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets,
            new[] { DriveService.Scope.Drive},
            "user",
            CancellationToken.None,
            new SavedDataStore(myStoredResponse)).Result;
}
DriveService _drive = new DriveService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential, 
    ApplicationName = _applicationName
});

Here is Googles example https://developers.google.com/drive/web/examples/dotnet

Upvotes: 6

Related Questions