GoogleJsonWebSignature ValidateAsync JWT 无效
Posted
技术标签:
【中文标题】GoogleJsonWebSignature ValidateAsync JWT 无效【英文标题】:GoogleJsonWebSignature ValidateAsync JWT invalid 【发布时间】:2020-10-16 21:39:23 【问题描述】:请帮助我了解 JWT 无效的谷歌授权。我正在使用以下参考来授权: 在我授权后,一两个小时后它仍然可以正常工作,但是随着时间的推移,我不知道确切多少天后,它无法正常工作并抛出异常,详细说明“JWT 无效”。 我正在使用参考: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。
这是我的代码:
`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;
`
谢谢大家!
【问题讨论】:
发生了两件事之一:1)您有一个具有到期日期的 cookie,并且您在到期日期之后访问服务器 2)连接即将结束,因此您必须授权每个新连接。跨度> 哦,谢谢jdweng! 【参考方案1】:经过一段时间的搜索,我将代码编辑为新版本,我不知道它是否解决了这个问题,但是当我尝试授权时,虽然我将计算机上的系统日设置为下个月,但它仍然有效。所以,我觉得我的回答是对的。这是我的新代码:
//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;
完整代码:
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);
【讨论】:
以上是关于GoogleJsonWebSignature ValidateAsync JWT 无效的主要内容,如果未能解决你的问题,请参考以下文章
va_list va_start va_arg va_end 使用说明
C 语言函数形参当中的 “...“ 是什么意思, va_start()va_arg()va_copy() 和 va_end()