0

I'm working on reading/sending gmail emails in c# with API requests. I have got an access token but it expires after one hour and further actions are not executed anymore. Could, please, someone help me with the procedure on how to get a new valid access token?

Thank you in advance!

EDIT:

This is a code from where I get authorization:

public static GmailService AuthenticateOauthGmail(string clientSecretJson, string userName)
    {
        try
        {
            if (string.IsNullOrEmpty(userName))
                throw new ArgumentNullException("userName");
            if (string.IsNullOrEmpty(clientSecretJson))
                throw new ArgumentNullException("clientSecretJson");
            if (!File.Exists(clientSecretJson))
                throw new Exception("clientSecretJson file does not exist.");

            // These are the scopes of permissions you need. It is best to request only what you need and not all of them
            string[] scopes = new string[] { "https://mail.google.com"};

            //UserCredential credential;
            using (var stream = new FileStream(clientSecretJson, FileMode.Open, FileAccess.Read))
            {
                string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);


                // Requesting Authentication or loading previously stored authentication for userName
                Variables.Credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                                                                         scopes,
                                                                         userName,
                                                                         CancellationToken.None,
                                                                         new FileDataStore(credPath, true)).Result;
                var newCredentials = GoogleWebAuthorizationBroker.ReauthorizeAsync(Variables.Credential, CancellationToken.None);
            }

            // Create Drive API service.
            return new GmailService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = Variables.Credential,
                ApplicationName = "Gmail Oauth2 Authentication Sample"
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine("Create Oauth2 account GmailService failed" + ex.Message);
            throw new Exception("CreateServiceAccountGmailFailed", ex);
        }
    }

This is how my Credentials.Token looks like credentials.Token

Since access token is expired, when trying to read mails, I get an error:

{
"error": {
    "code": 401,
    "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [
        {
            "message": "Invalid Credentials",
            "domain": "global",
            "reason": "authError",
            "location": "Authorization",
            "locationType": "header"
        }
    ],
    "status": "UNAUTHENTICATED"
   }
}

I have nuget package Google.Apis.Auth. Should I use another one?

nellop
  • 1
  • 1
  • 1
    Please edit your question and include your code and i will see if i can help. are you using the Google .net client library if so it should be handling all that for you. – Linda Lawton - DaImTo Jan 05 '21 at 12:44
  • Hi @DaImTo, I have edited my post. Could you, please, go through it once more? Thank you :) – nellop Jan 07 '21 at 10:43

1 Answers1

0

For extended access to google services you cannot issue just one access token, you should use refresh tokens. See Basic Steps 5: https://developers.google.com/identity/protocols/oauth2#:~:text=If%20your%20application%20needs%20access,long%20as%20they%20remain%20valid.

You can use the RefreshTokenAsync method on this class: https://googleapis.dev/dotnet/Google.Apis.Auth/latest/api/Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.html

Selmir Aljic
  • 268
  • 2
  • 9
  • Hi @Semlir Aljic, thank you for your reply :) I know I should use refresh token but not sure how to use them since API request needs access token in header. Or should I send refresh token in header? – nellop Jan 08 '21 at 15:16
  • Hey @nellop I've updated my answer. I hope this is enough for you if not, there have been similar questions before on stack overflow you can find more info here: https://stackoverflow.com/questions/22357348/google-apis-client-for-csharp-auth-using-refresh-token – Selmir Aljic Jan 08 '21 at 20:17
  • Thank you so much @Selmir Aljic, I successfully got a new access token :) – nellop Jan 13 '21 at 07:45
  • @nellop You’re welcome, I’m glad I could be of help :) – Selmir Aljic Jan 13 '21 at 16:26