13

So I have this code
My question is how do I configure the UserCredential if I'm already authenticated via OAuth?

The current scenario is the code will display another login page redirecting to google. Since I'm already authenticated via OAuth using asp.net MVC and I already have the token how to I get rid of the GoogleWebAuthorizationBroker and directly pass the token?

string[] scopes = new string[] {PlusService.Scope.PlusLogin,
                                             PlusService.Scope.UserinfoEmail,
                                             PlusService.Scope.UserinfoProfile};

UserCredential credential = 
GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets
{
    ClientId = "xxx.apps.googleusercontent.com",
    ClientSecret = "xxxx"
},
    scopes,
    Environment.UserName,
    CancellationToken.None,
    new FileDataStore("Store")).Result;

PlusService service = new PlusService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = "ArcaneChatV2",
});

PeopleResource.ListRequest listPeople = service.People.List("me", PeopleResource.ListRequest.CollectionEnum.Visible);
listPeople.MaxResults = 10;
PeopleFeed peopleFeed = listPeople.Execute();
var people = new List<Person>();

I'm just new to this kind of stuff.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Prince Jea
  • 5,524
  • 7
  • 28
  • 46

2 Answers2

27

Assuming you already have the tokens you can do the following

string[] scopes = new string[] {
    PlusService.Scope.PlusLogin,
    PlusService.Scope.UserinfoEmail,
    PlusService.Scope.UserinfoProfile
};

var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
    ClientSecrets = new ClientSecrets
    {
        ClientId = "xxx.apps.googleusercontent.com",
        ClientSecret = "xxxx"
    },
    Scopes = scopes,
    DataStore = new FileDataStore("Store")
});

var token = new TokenResponse { 
    AccessToken = "[your_access_token_here]",
    RefreshToken = "[your_refresh_token_here]"
};

var credential = new UserCredential(flow, Environment.UserName, token); 

Then you can pass your credentials to the service's initializer

Reference Google API Client Libraries > .NET > OAuth 2.0

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • Just a follow up question @Nkosi how to set the refresh token in UserCredential? credential.Token.RefreshToken = "[your_access_token_here]" is that the right way? Because I kept getting "The access token has expired but we can't refresh it". – Prince Jea Jul 18 '16 at 06:18
  • @PrinceJea. You include the refresh token when you create the `TokenResponse`. GoogleAuthorizationCodeFlow will get a new access token based on your refresh token and client secrets. – Nkosi Jul 18 '16 at 09:16
  • 1
    how to get the refresh token exactly? This is what I've tried **context.Identity.AddClaim(new Claim("urn:google:refreshtoken", context.RefreshToken, ClaimValueTypes.String, "Google"));** I'm still getting errors. – Prince Jea Jul 18 '16 at 10:09
  • Did you read any of the reference material I linked to? I think I quoted something in your other question http://stackoverflow.com/a/38432284/5233410 – Nkosi Jul 18 '16 at 10:10
  • Yes I'm reading it for days lol. I'm just stuck on getting user circles right now. I've done it on facebook but the google api gave me headaches. – Prince Jea Jul 18 '16 at 10:14
  • OK. Do you get a refresh token when you authenticate your users? – Nkosi Jul 18 '16 at 10:15
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/117589/discussion-between-prince-jea-and-nkosi). – Prince Jea Jul 18 '16 at 10:16
  • why there is a client secret needed if I am doing a native android authentication, I dont have client secret. This is only for web applications i believe – Emil Mar 21 '18 at 01:00
  • 1
    If you don't have the refresh token, but you are getting an error indicating your token has expired then you need to set the ExpiresInSeconds property on the TokenResponse to something which seems to prevent the need for a RefreshToken if you are doing a once off server call like I was. I found that 60 seconds didn't work, but larger numbers did. It's not very scientific I know. – The Senator Jul 13 '18 at 14:41
7

We can create GoogleCredential directly from the access token and use it instead of UserCredential as well. I just think it might be helpful for someone. Here is a code snippet of GmailService initialization:

GoogleCredential cred = GoogleCredential.FromAccessToken(accessToken);
GmailService service = new GmailService(new BaseClientService.Initializer {HttpClientInitializer = cred});
OL.
  • 201
  • 3
  • 13