1

Please help me about JWT invalid google authorize. I am using references below to authorize: After I authorize, an hour or two later It still work perfect, but along time later, I do not know exactly how many days later, it not working and throw exeption with detail "JWT invalid". I am using references: Google.Apis.Auth, Google.Apis.Auth.OAuth2, oogle.Apis.Auth.OAuth2.Flows, Google.Apis.Auth.OAuth2.Responses, Google.Apis.Gmail.v1, Google.Apis.Util.Store.

That is my code:

`public static async Task<string> AuthorizeAsync()
    {
        UserCredential credential = null;
        bool expired = false;
        string accessToken = string.Empty;

        var di = Directory.CreateDirectory(Global.GOOGLE_AUTHORIZE_FOLDER);
        string path =di.FullName;

        var secrets = new ClientSecrets
        {
            ClientId = Global.clientID,
            ClientSecret = Global.clientSecret,
        };

        /**/
        try
        {
            /*check google acount authorize file*/
            credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                         secrets, new[] { "email", "profile", GmailService.Scope.MailGoogleCom },
                         "user", CancellationToken.None, new FileDataStore(path));
            var jwtPayload = GoogleJsonWebSignature.ValidateAsync(credential.Token.IdToken, new GoogleJsonWebSignature.ValidationSettings() { ForceGoogleCertRefresh=true}).Result;
            //var jwtPayload = GoogleJsonWebSignature.ValidateAsync(credential.Token.IdToken).Result;
            accessToken = credential.Token.AccessToken;
        }
        catch (Exception ex)
        {
            string msg = ex.Message;
            if (ex.InnerException != null)
                msg = ex.InnerException.Message;

            if (msg.Contains("JWT has expired"))
            {
                expired = true;
            }
            else if (msg.Contains("JWT invalid"))
            {
                XtraMessageBox.Show("JWT invalid" , "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return string.Empty;
            }
            else
            {
                XtraMessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return string.Empty;
            }
        }

        if (expired)
        {
            accessToken = AuthorizeWithRefreshToken(credential, secrets);
        }

        return accessToken;
    }

    public static string AuthorizeWithRefreshToken(UserCredential credential, ClientSecrets secrets)
    {
        string accessToken = string.Empty;
        try
        {
            var newToken = new TokenResponse { RefreshToken = credential.Token.RefreshToken };
            var googleCredentials = new UserCredential(new GoogleAuthorizationCodeFlow(
                new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = secrets
                }), credential.UserId, newToken);

             accessToken = credential.GetAccessTokenForRequestAsync().Result;
        }
        catch (Exception ex)
        {
            XtraMessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        return accessToken;
    }`

Thanks everyone!

Andreis IT
  • 21
  • 2
  • One of two things is happening 1) You have a cookie with an expiration date and you accessing the server after the expiration date 2) The connection is ending so you have to authorize every new connection. – jdweng Jun 26 '20 at 09:58
  • oh, so thanks jdweng! – Andreis IT Jul 01 '20 at 01:09

1 Answers1

1

After for along time to search, I edited my code to new version, I don't know It solved that problem or not but when I tried authorization, it's working although I set system day on my computer to next month. So, I think my answer is true. Here my new code:

//authorize at first time
                var credential = await dsAuthorizationBroker.AuthorizeAsync(
                      secrets, new[] { "email", "profile", GmailService.Scope.MailGoogleCom },
                     Global.GetUserId(), CancellationToken.None, new FileDataStore(path));
                var jwtPayload = GoogleJsonWebSignature.ValidateAsync(credential.Token.IdToken, new GoogleJsonWebSignature.ValidationSettings() { ForceGoogleCertRefresh = true }).Result;
//later times I used code
var credential = await dsAuthorizationBroker.AuthorizeAsync(secrets, new[] { "email", "profile", GmailService.Scope.MailGoogleCom },
                      Global.GetUserId(), CancellationToken.None, new FileDataStore(path));

            if (credential.Token.IsExpired(SystemClock.Default))
            {
                accessToken = credential.Flow.RefreshTokenAsync(Global.GetUserId(), credential.Token.RefreshToken, CancellationToken.None).Result.AccessToken;
            }
            else
            {
                accessToken = credential.Token.AccessToken;
            }

Full code:

public static class GoogleAuthorizeTool
{
    public static async Task<string> AuthorizeAsync()
    {
        string accessToken = string.Empty;

        var di = Directory.CreateDirectory(Global.GOOGLE_AUTHORIZE_FOLDER);
        string path = di.FullName;

        var secrets = new ClientSecrets
        {
            ClientId = Global.clientID,
            ClientSecret = Global.clientSecret,
        };

        /**/
        try
        {
            var credential = await dsAuthorizationBroker.AuthorizeAsync(secrets, new[] { "email", "profile", GmailService.Scope.MailGoogleCom },
                      Global.GetUserId(), CancellationToken.None, new FileDataStore(path));

            if (credential.Token.IsExpired(SystemClock.Default))
            {
                accessToken = credential.Flow.RefreshTokenAsync(Global.GetUserId(), credential.Token.RefreshToken, CancellationToken.None).Result.AccessToken;
            }
            else
            {
                accessToken = credential.Token.AccessToken;
            }
        }
        catch (Exception ex)
        {
            var _e = ex;
            if (ex.InnerException != null)
                _e = ex.InnerException;

            XtraMessageBox.Show(_ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
           
        }
        return accessToken;
    }
}

public class ForceOfflineGoogleAuthorizationCodeFlow : GoogleAuthorizationCodeFlow
{
    public ForceOfflineGoogleAuthorizationCodeFlow(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"
        };
    }
};

public class dsAuthorizationBroker : GoogleWebAuthorizationBroker
{
    public static string RedirectUri;

    public new static async Task<UserCredential> AuthorizeAsync(
        ClientSecrets clientSecrets,
        IEnumerable<string> scopes,
        string user,
        CancellationToken taskCancellationToken,
        IDataStore dataStore = null)
    {
        var initializer = new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = clientSecrets,
        };
        return await AuthorizeAsyncCore(initializer, scopes, user,
            taskCancellationToken, dataStore).ConfigureAwait(false);
    }

    private static async Task<UserCredential> AuthorizeAsyncCore(
        GoogleAuthorizationCodeFlow.Initializer initializer,
        IEnumerable<string> scopes,
        string user,
        CancellationToken taskCancellationToken,
        IDataStore dataStore)
    {
        initializer.Scopes = scopes;
        initializer.DataStore = dataStore ?? new FileDataStore(Folder);
        var flow = new ForceOfflineGoogleAuthorizationCodeFlow(initializer);
        return await new AuthorizationCodeInstalledApp(flow,
            new LocalServerCodeReceiver())
            .AuthorizeAsync(user, taskCancellationToken).ConfigureAwait(false);
    }
}
Andreis IT
  • 21
  • 2