TokenResponseException - 错误:“invalid_grant”,描述:“”,Uri:“" [英] TokenResponseException - Error:"invalid_grant", Description:"", Uri:""

查看:396
本文介绍了TokenResponseException - 错误:“invalid_grant”,描述:“”,Uri:“"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的代码是 - 使用Google Calendar API和Gmail API以及来自Google的OAuth2身份验证的MVC应用。代码起作用。加载页面后,将显示来自两种服务的数据。我有一个Javascript计时器刷新数据以一定的时间间隔(20分钟)。因此,一切都按预期工作,直到某个时间点(经过一段时间我猜)它开始抛出一个异常:错误:invalid_grant,描述:,Uri:。这个异常没有InnerException,只有这个错误信息和StackTrace中的这个信息(在屏幕截图中):



我真的很感激,如果有人有一个想法可能是什么原因造成的错误。在堆栈跟踪消息中,c:\ code \ google.com ...行是什么,我的磁盘上没有c:\ code文件夹。我发现了一些与同一个错误相关的帖子,但不幸的是他们无助于理解这个问题。也许有更多的细节,像这个截图有人有关于这个问题的更多信息。非常感谢。



我发现的是,AppPool回收临时解决了问题。但是,过了一段时间后,它又回来了。它与AppPool回收有什么关系?

解决方案

好吧,在阅读更多内容后,我发现了这个异常的原因。



https://developers.google.com/accounts/docs/OAuth2#expiration



https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtAuthorization?#helpme



格兰特无效:已超出刷新令牌限制(默认值为25)。
就是这样。



根据以下文档:每个Google用户帐户目前有25个令牌限制。如果用户帐户有25个有效令牌,则下一个验证请求会成功,但会悄悄地使最旧的未完成令牌无效,而不会有任何用户可见的警告。



如果应用程序尝试使用一个无效的刷新标记,返回invalid_grant错误响应。每个唯一一对OAuth 2.0客户端和Google Analytics帐户的限额为25个刷新标记(请注意,此限制可能会发生变化)。

我们了解到,它们限制了#刷新标记为25,但当你需要超过这个限制时,他们不会说什么做。呃......我一直在试验,并找到了解决方法如何绕过这个限制。似乎的确回收应用程序池解决了问题(当然直到下一个25-限制达到)。我们可以从IIS手动回收AppPool或运行以下命令:

  c:\Windows\System32\inetsrv\\ \\appcmd.exe回收apppool /apppool.name:AppPoolName 

您可以安排该命令每晚执行或每小时,无论... ...

但我发现有一个编程解决方案:



覆盖OnException方法为你的控制器(这是为MVC应用程序)

pre $保护覆盖无效OnException(ExceptionContext filterContext)
{
if(filterContext.ExceptionHandled)return;

//记录异常详情
Global.LogException(filterContext.Exception,EventLogEntryType.Error);

if(filterContext.Exception.Message.Contains(invalid_grant))
{
//格式无效:已超出刷新令牌限制(默认值为25)。
// https://developers.google.com/accounts/docs/OAuth2#expiration
// https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmt授权?#helpme

Global.RecycleAppPool();
Global.LogException(新的异常(AppPool已被回收),EventLogEntryType.Information);
Response.Redirect(Index);
}

var actionName = filterContext.RouteData.Values [action]。ToString();

//返回友好错误消息
var errorMessage = string.Format(Action {0} failed with error:{1}。Please try again。,actionName,filterContext.Exception。信息);
filterContext.Result = Content(errorMessage);

filterContext.ExceptionHandled = true;
base.OnException(filterContext);





$ b

其中RecycleAppPool是这样定义的(这个操作很快,不像重新启动IIS :):
$ b $ pre $ public static void RecycleAppPool()
{
ServerManager serverManager = new ServerManager();
ApplicationPool appPool = serverManager.ApplicationPools [Homepage];
if(appPool!= null)
{
if(appPool.State == ObjectState.Stopped)appPool.Start();
else appPool.Recycle();






$ b因此,在发生invalid_grant异常的情况下,吞噬:已记录,应用程序池将被回收,刷新令牌的限制被重置。希望这会有所帮助。



如果您发现某些问题,请让我知道。


I have code that works - MVC app using Google Calendar API and Gmail API with OAuth2 Authentication from Google. The code works. When the page is loaded the data from both services is displayed. And I have a Javascript timer to refresh the data with certain interval (20 min). So everything works as expected until at some point of time (after some time interval I guess) it starts throwing an exception: Error:"invalid_grant", Description:"", Uri:"". The exception has no InnerException and has only that error message and this info in StackTrace (here on the screenshot):

I would really appreciate if someone has an idea what could be the reason for that error. And what is that "c:\code\google.com...." line in stack trace message, I have no "c:\code" folder on my disk. I have found a few posts related to the same error, but unfortunately they didn't help to understand the problem. Maybe with more details like this screenshot someone has more info on the subject. Thanks a lot.

What I found out - is that AppPool recycling temporary solves the problem. But then, after some time, it comes back again. What doest it have to do with AppPool recycling?

解决方案

Well, after more reading I found the reason of this exception.

https://developers.google.com/accounts/docs/OAuth2#expiration

https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtAuthorization?#helpme

Invalid Grant: The refresh token limit has been exceeded (default is 25). That's all.

According to these documentation: There is currently a 25-token limit per Google user account. If a user account has 25 valid tokens, the next authentication request succeeds, but quietly invalidates the oldest outstanding token without any user-visible warning.

If the application attempts to use an invalidated refresh token, an invalid_grant error response is returned. The limit for each unique pair of OAuth 2.0 client and Google Analytics account is 25 refresh tokens (note that this limit is subject to change).

Understood, they limit # of refresh tokens to 25, but they don't say what to do when you need to go above that limit. Arghhh... I have been experimenting and found a solution how to bypass that limitation. It seems indeed that recycling the Application Pool solves the problem (of course untill next 25-limit is reached). We can manually recycle the AppPool from IIS or by running the command:

c:\Windows\System32\inetsrv\appcmd.exe recycle apppool /apppool.name:AppPoolName

You can schedule that command to execute every night or every hour, whatever...

But I found a have a programmatic solution:

Override OnException method for your controller (it's for MVC app)

protected override void OnException(ExceptionContext filterContext)
{
    if (filterContext.ExceptionHandled) return;

    // Log exception details
    Global.LogException(filterContext.Exception, EventLogEntryType.Error);

    if (filterContext.Exception.Message.Contains("invalid_grant"))
    {
        // Invalid Grant: The refresh token limit has been exceeded (default is 25).
        // https://developers.google.com/accounts/docs/OAuth2#expiration
        // https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtAuthorization?#helpme

        Global.RecycleAppPool();
        Global.LogException(new Exception("AppPool has been recycled"), EventLogEntryType.Information);
        Response.Redirect("Index");
    }

    var actionName = filterContext.RouteData.Values["action"].ToString();

    // Return friendly error message
    var errorMessage = string.Format("Action {0} failed with error: {1}. Please try again.", actionName, filterContext.Exception.Message);
    filterContext.Result = Content(errorMessage);

    filterContext.ExceptionHandled = true;
    base.OnException(filterContext);
}

Where RecycleAppPool is defined like this (this operation is fast, not like restarting IIS :):

public static void RecycleAppPool()
{
    ServerManager serverManager = new ServerManager();
    ApplicationPool appPool = serverManager.ApplicationPools["Homepage"];
    if (appPool != null)
    {
        if (appPool.State == ObjectState.Stopped) appPool.Start();
        else appPool.Recycle();
    }
}

So, in case of invalid_grant exception, the exception "swallowed": logged, apppool is recycled and the limit for refresh tokens is reset. Hope this helps.

Please let me know if you find some issues.

这篇关于TokenResponseException - 错误:“invalid_grant”,描述:“”,Uri:“"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆