Paweł Chojnacki
Paweł Chojnacki

Reputation: 15

How can I fill native app credentials with web app generated token in Google API?

I'm doing some web based app that shows user calendar from database entries. In this web app user can authenticate it's Google Calendar account, through JavaScript library. Then I want to share this access authorization with my desktop service. Desktop service is written in C#.

Does anybody knows how can I fill up CalendarService class in C# having following code?

Javascript:

function auth() {
            var config = {
                'client_id': "myID",
                'scope': "https://www.googleapis.com/auth/calendar"
            };
            gapi.auth.authorize(config, function () {
                console.log('login complete');
                console.log(gapi.auth.getToken());
            });
        }

Then there is my C# code in Windows Service

var tokenResponse = new TokenResponse
{
        AccessToken = tokenCopiedFromJavascriptObject,
        Issued = propertyCopiedFromJavascriptObject,
        TokenType = "Bearer",
        Scope = CalendarService.Scope.Calendar,
        RefreshToken = "3600"
};

var authorizationCodeFlowInitializer = new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = new ClientSecrets()
            {
                ClientId = myIdForDesktopApp,
                ClientSecret = ClientSecretForDestopApp
            },
            Scopes = new[] { CalendarService.Scope.Calendar },
            Clock = Google.Apis.Util.SystemClock.Default
        };
        var authorizationCodeFlow = new GoogleAuthorizationCodeFlow(authorizationCodeFlowInitializer);
        _credentials = new UserCredential(authorizationCodeFlow, _calendarId, tokenResponse);

        _service = new CalendarService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = _credentials,
            ApplicationName = "Fast and Easy Reservation System"
        });
        const string meeting = "Some fancy meeting";
        var e = _service.Events.QuickAdd("primary", meeting).Execute();
    }

Is there any hope to get this working? For example I have 2 apps (web and desktop) in my Google API Project. These are within one project so I think it should work as a hybrid app and they should share one authorization token.

Object returned by JS auth function have following properties: access_token client_id expires_at expires_in issued_at response_type scope token_type

Upvotes: 0

Views: 145

Answers (1)

Paweł Chojnacki
Paweł Chojnacki

Reputation: 15

I've made Controler in ASP.NET MVC application to handle Javascript code and send token to my database. In order to avoid incompatible application types (web and native), my Windows Service uses client_secrets.json file from web type application. In order to precisely control flow of application and somehow cheat that native service is web application, I have loaded just client_id and client_secret from client_secrets.json (web).

            var flow = new GoogleAuthorizationCodeFlow(
            new GoogleAuthorizationCodeFlow.Initializer
            {
                ClientSecrets = new ClientSecrets()
                {
                    ClientId = "some-numbersAndLettersxxxxxxxxxx.apps.googleusercontent.com",
                    ClientSecret = "xxxxxxxxxxxxxx"
                }
            });

Then, I loaded token from database in my app and assigned it.

var token = new TokenResponse
        {
            RefreshToken = "ya29.UAH2llQasSADfga32fWay3aqi1pb0AUwAWy_WzbPNyNkYCRPhe5_zBbEG94TZafV8pBMHzC8Q"
        };

After well prepared flow and token I was able to create credentials object.

var credential = new UserCredential(flow, clientId, token);

Now, native app pretends to be web application and it can access all user data without additional consent screens.

Upvotes: 0

Related Questions