Samuel
Samuel

Reputation: 2019

How to set AccessType as offline in Google.Apis.Core 1.9 in C#

I am using Google APIs for OAuth2 version 1.9 and trying to send AccessType as offline and ApprovalPrompt as force everytime so that I get a refresh token. I know there are many questions on this topic here in various api versions and languages. However, none of the solutions works with the new google library.

I am using the following to get the flow:

private IAuthorizationCodeFlow GetAuthorizationCodeFlow()
        {
            var flow = new GoogleAuthorizationCodeFlow(
                new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = new ClientSecrets
                    {
                        ClientId =
                            "***",
                        ClientSecret = "***"
                    },

                    Scopes = new string[]
                                 {
                                     CalendarService.Scope.Calendar,
                                     PlusService.Scope.UserinfoProfile,
                                     PlusService.Scope.UserinfoEmail,
                                     PlusService.Scope.PlusLogin,
                                     "https://www.googleapis.com/auth/contacts.readonly"
                                 }
                });

            return flow;            
        }

and then using the following code to get the token:

var token = flow.ExchangeCodeForTokenAsync("me", code,
                    uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;

This is where I need the refresh token every time (not just the first time) so I want to set the AccessType and ApprovalPrompt.

Upvotes: 4

Views: 3679

Answers (1)

Dhanuka777
Dhanuka777

Reputation: 8636

I also had the exact same question. Credit goes to this post. I will paste my code as I had to make a small change to get it working. (to use GoogleAuthorizationCodeFlow.Initializer in the constructor rather than AuthorizationCodeFlow.Initializer)

Implement your own GoogleAuthorizationCodeFlow class and set the "offline" access in the AccessType property. This will give you the refreshtoken.

 public class OfflineAccessGoogleAuthorizationCodeFlow : GoogleAuthorizationCodeFlow
    {
        public OfflineAccessGoogleAuthorizationCodeFlow(GoogleAuthorizationCodeFlow.Initializer initializer) : base(initializer) { }

        public override AuthorizationCodeRequestUrl CreateAuthorizationCodeRequest(string redirectUri)
        {
            return new GoogleAuthorizationCodeRequestUrl(new Uri(AuthorizationServerUrl))
            {
                ClientId = ClientSecrets.ClientId,
                Scope = string.Join(" ", Scopes),
                RedirectUri = redirectUri,
                AccessType = "offline",
                ApprovalPrompt = "force"
            };
        }
    };

It's unfortunate that we can't set the "access_type" from GoogleAuthorizationCodeFlow Initializer.

Also, I use following code to retrieve the refresh token,

Google.Apis.Auth.OAuth2.Responses.TokenResponse token = new Google.Apis.Auth.OAuth2.Responses.TokenResponse();
            //// Checks if the token is out of date and refresh the access token using the refresh token.
            if (result.Credential.Token.IsExpired(SystemClock.Default))
            {
                //If the token is expired recreate the token
                token = await result.Credential.Flow.RefreshTokenAsync(userid.ToString(), result.Credential.Token.RefreshToken, CancellationToken.None);

                //Get the authorization details Results 
                result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).AuthorizeAsync(cancellationToken);
            }

Upvotes: 6

Related Questions