OAuth 2 Google API 刷新令牌为空

2024-01-08

我正在开发一个 Asp.NET MVC5 应用程序按照这个谷歌示例代码 https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth.

我希望应用程序经过身份验证并由用户创建访问令牌(配置阶段),稍后我需要能够使用刷新令牌调用 Google API'(在我的情况下是目录 API)(无需用户干预,例如“离线”)。

控制器:

public async Task<ActionResult> IndexAsync(CancellationToken cancellationToken)
{
    var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
                        AuthorizeAsync(cancellationToken);

        if (result.Credential != null)
        {
          var service = new Google.Apis.Admin.Directory.directory_v1.DirectoryService(new BaseClientService.Initializer
                        {
                            HttpClientInitializer = result.Credential,
                            ApplicationName = "My Application"
                        });
                      return View();
        }
        else
        {
             return new RedirectResult(result.RedirectUri);
        }
}         

流元数据实现。 (我正在使用稍微修改过的 FiledataStore (GoogleFileDataStore))

public class AppFlowMetadata : FlowMetadata
    {
        //Move to settings
        static readonly string clientId = "xxxccnvofsdfsfoj.apps.googleusercontent.com";
        static readonly string clientsecret = "xxxxxxxxxxLvtC6Qbqpp4x_";
        static readonly string datastore = "AdminSDK.Api.Auth.Store";


         private static readonly IAuthorizationCodeFlow flow =
            new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = new ClientSecrets
                    {
                        ClientId = clientId,
                        ClientSecret = clientsecret
                    },
                    Scopes = new[] { DirectoryService.Scope.AdminDirectoryUser, DirectoryService.Scope.AdminDirectoryUserAliasReadonly },
                    DataStore = new GoogleFileDataStore(datastore)
                });


        public override string GetUserId(Controller controller)
        {           
            return ConfigHelper.UserID.ToString();
        }

        public override IAuthorizationCodeFlow Flow
        {
            get { return flow; }
        }
    }

当我调用 IndexAsync 控制器时,由于用户之前没有访问令牌,因此它会在用户登录 Google 帐户后创建一个新的访问令牌。
这是一个示例访问令牌,

{"access_token":"ya29.5gBOszGO-oYJJt4YZfF6FeaZth1f69_.....","token_type":"Bearer","expires_in":3600,"Issued":"2014-12-24T16:02:32.014+05:30"}

问题1:为什么这里没有存储Refreshtoken?如何检索刷新令牌? 问题2:如果获得了refreshtoken,我应该如何修改代码来创建新的access token并调用API(当accesstoken过期时)? [我提到这个问题 https://stackoverflow.com/questions/25144667/using-the-youtube-v3-data-api-for-net-how-is-it-possible-to-get-a-refresh-toke,但对于缺少刷新令牌没有正确的答案。


找到了Google API离线访问获取refresh token并使用refresh token创建新的accesstoken的解决方案,

问题1:为什么没有存储刷新令牌?如何检索刷新令牌?

我必须在请求中将 access_type 设置为离线(默认情况下为在线)。正如这里提到的 https://developers.google.com/accounts/docs/OAuth2WebServer#overview

我必须为 GoogleAuthorizationCodeFlow 类编写自己的实现。谢谢这个帖子。 https://stackoverflow.com/questions/22094599/google-analytics-oauth-with-accesstype-offline-in-c-sharp

 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"
            };
        }
    };

问题2:..我应该如何修改代码来创建新的访问令牌并调用API?

    //try to get results
    var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
                    AuthorizeAsync(cancellationToken);


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

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

这对我有用!希望这会帮助其他人......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OAuth 2 Google API 刷新令牌为空 的相关文章

  • MVC3 RenderPartial 跨多个页面缓存

    谁能告诉我是否可以跨多个页面缓存 RenderPartial 我有一个用于用户配置文件的 RenderPartial 除非用户更新其配置文件 否则它实际上不会改变 所以我真的不想每次加载页面时都回去获取他 她的个人资料 我宁愿传递部分内容
  • 是否应该在使用 MVC 的每个视图中使用 ViewModel?

    我了解您使用 ViewModel 来存储来自其他模型和源的不同数据以在视图中使用 因为模型并不总是包含您想要的内容 我试图弄清楚为每个视图使用 ViewModel 是否合适 我问的原因是出于一致性原因 您可以有一个仅需要模型本身的视图 以及
  • 是否可以手动更新 ModelState.IsValid ?

    我想尽可能使用内置的验证功能 我还想对 CRUD 方法使用相同的模型 但是 由于无法使用标准模式完成下拉列表 因此我必须手动验证它 在回发方法中 我只想验证下拉列表并将此结果添加到 ModelState 中 这样我就不必验证使用数据注释完成
  • ASP.NET MVC 使用类型化模型将模型与单选按钮列表进行两种方式数据绑定

    我有一个由单选按钮矩阵组成的 mvc 视图 每行单选按钮都在一个组中 代表模型中的一个键入对象 使用各种博客和帖子的指导 我已成功将发布的表单结果绑定到控制器操作中的类型化模型数组 但是似乎无法成功反转效果并将现有模型绑定到单选按钮 同时保
  • ASP.Net MVC 在哪里从实体转换为视图模型?

    标题几乎解释了一切 这是我在我们的项目中尝试做的最后一件事 我们的结构是一个服务库 其中包含这样的功能
  • MVC 5:模型中的字典绑定到视图中的一系列复选框?

    当我将模型发布到控制器以保存它时 控制器会得到一个空字典 哪里出了问题 绑定工作有什么特别要做的吗 我的模型有这个属性 public Dictionary
  • 无法解析请求正文

    我一直在尝试解决以下错误 但无法解决 下面是代码 HttpPost public async Task
  • 如何使用带有 Scripts.Render 的 ASP MVC 4 捆绑包的脚本延迟属性

    我浏览了 Google 和 Stackoverflow 但没有找到答案 是否有任何内置方法可以使捆绑包按延迟执行 或者有人知道有人为此编写的扩展帮助器方法吗 尝试将 Web Optimization 升级到版本 1 1 0Codeplex
  • MVC WebGrid 设置渲染的ID

    使用 MVC 3 中的 WebGrid 如何在呈现时指定控件的名称 即呈现时表的 id var someGrid new WebGrid source Model Users defaultSort Name rowsPerPage 50
  • 在实体框架中不使用 Dispose 或 using()

    我一路上正在编写一个网络应用程序并学习实体框架 如果我做错了什么 我很好奇 我在查询时没有使用过 dispose 或 using 语句 我的存储库示例 public User GetUserById int sessionId var us
  • global.asax Application_AcquireRequestState 与 Application_BeginRequest

    有什么不同 我想在我的应用程序中实现语言下拉选择 因此 当选择选定的语言时 将设置线程区域性并重新加载页面 Like so Thread CurrentThread CurrentCulture CultureInfo CreateSpec
  • ASP.NET MVC - 重写 FormMethod.Get 查询字符串?

    我有一个简单的表单 只有一个文本框和一个提交按钮 该表单基本上将文本框中的值作为查询字符串发送到不同的页面 当我单击提交按钮时 查询字符串采用以下格式 例如 mysite com TargetCode Test1 我希望它以这种格式显示 m
  • 重载控制器动作

    几分钟前 当我尝试在我的一个控制器中重载操作时 我有点惊讶 I had public ActionResult Get return PartialView return all things I added public ActionRe
  • 识别 ASP.NET MVC 代码中的 Angular js AJAX 调用

    我正在使用 ASP NET MVC 和 AngularJS 开发一个示例应用程序 在服务器端代码中 我编写了一个Action过滤器属性 其中我需要检查请求是普通请求 浏览器 还是AJAX请求 public override void OnA
  • filters.Add 与 FilterProviders.Providers.Add

    我遇到了一个示例 MVC3 代码 其中包含以下内容Global asax file public static void RegisterGlobalFilters filters Add new MyFilter1 var provide
  • 从业务逻辑类重定向 asp.net mvc 页面

    我在业务逻辑层中调用一个静态方法 出于我在这里不会提及的目的 该方法需要自行进行重定向 而不是将信息返回到控制器以进行重定向 我认为我需要使用 HttpContext 对象 但正在努力创建路由 我不能简单地执行 context Respon
  • 删除高图表上的导出和打印按钮插件

    我正在使用 MVC 目前正在使用 highchart 我正在使用 Exporting js 以便用户可以打印或导出 highchart 图表 我的视图中有两个图表 我想禁用其中一个图表的打印和导出 我怎样才能做到这一点 Exporting
  • 创建视图中可用的自定义助手

    我有太多文本实用方法 例如MakeShortText string text int length RemoveTags string text TimeAgo DateTime date 和别的 我想从单独的助手访问它们 如下一个示例所示
  • asp.net mvc 未收到包含句点的 GET 请求

    我将 net4 5rc 与 MVC4 0rc 一起使用 下面的代码取自 MVC webapi 应用程序 但我对于常规 asp net mvc 也有相同的行为 我的注册路由代码如下所示 routes IgnoreRoute resource
  • 为什么 ASP.Net MVC Range 属性采用类型?

    我只是想知道为什么范围验证属性可以采用类型和两个字符串作为参数 这是为了根据枚举或类似的东西验证字符串吗 另外 我想做的是找到一种简单的方法来验证必须出现在枚举中的 3 个字符的字符串 有什么建议吗 谢谢 亚历克斯 我确实发现你提到的 Ra

随机推荐

  • 如何在代码隐藏中将 FrameworkElement.Width 属性设置为 QualifiedDouble 的值?

    我试图将我的一个控件的宽度属性设置为qualifiedDouble 如 MSDN 上所述 http msdn microsoft com en us library system windows frameworkelement width
  • Keras Embedding 层中的 mask_zero 如何工作?

    我想mask zero True当输入值为 0 时将输出 0 因此后续层可以跳过计算或其他操作 如何mask zero works 例子 data in np array 1 2 0 0 data in shape gt gt gt 1 4
  • 根据语言更改文本

    我正在使用带有语言切换器的 Wordpress 在各种语言之间进行切换 在模板中 我使用这段代码来切换硬编码文本 This is english This is another language 我有一个侧边栏 但它是通过各种小部件创建的
  • 使用 io.TextIOWrapper 包装打开的流

    如何包装一个开放的二进制流 Python 2file Python 3io BufferedReader an io BytesIO 在一个io TextIOWrapper 我正在尝试编写不改变即可工作的代码 在 Python 2 上运行
  • Xcode 6 和 Swift 中视图之间类似 Snapchat 的滑动导航)

    我一直在尝试使用滑动手势识别器和嵌入式导航控制器在我的应用程序中的视图控制器之间实现滑动导航 但它看起来与 Snapchat 的导航并不接近 实现搜索功能最有效 最合适的方法是什么 我确实是 Swift 和编程的新手 我会很感激每一个有用的
  • 找不到模块错误:没有名为“chart_studio”的模块

    I run pip install chart studio在 jupyter 笔记本中 然后运行这段代码时 import numpy as np import pandas as pd import cufflinks as cf imp
  • 如何用JQ补数字?

    我想向数字中的字符串添加前导 尾随零 结果字符串需要包含 01 或 001 而不是 1 我注意到项目https github com joelpurra jq zeros但我从包管理器 dnf fedora 安装了 jq 所以需要一些jqn
  • 绑定复选框列表

    我需要一种简单的方法来绑定复选框列表asp net C 我从数据库 Id Name 和 IsActive 中提取 3 列 Id 和 Name 我想通过它的名字就可以清楚地看出 IsActive 将用于显示选中和未选中的框 我只是想知道 数据
  • 在 Angular 2 中从子组件更新父组件属性

    我在用着 input从父组件接收属性 以便激活子组件元素之一中的 CSS 类 我能够从父母那里接收财产并激活班级 但这只有效一次 我从父级接收的属性是一个布尔数据类型 当我将其状态设置为false从子组件开始 它在父组件中不会改变 Plun
  • webpack 4 给出背景: url([object Module]) 作为背景图像

    我在设置 web pack 4 和 svg sprite loader 将 svg 图标渲染为背景图像时遇到问题 我遵循 svg sprite loader 官方文档中的这些说明 https github com kisenka svg s
  • 使用 OpenCV 和 PyAudio 同步音频和视频

    我已经让 OpenCV 和 PyAudio 都工作了 但是我不确定如何将它们同步在一起 我无法从 OpenCV 获取帧速率并测量帧时时刻刻变化的调用时间 然而 对于 PyAudio 来说 它的基础是获取一定的采样率 我如何将它们同步到相同的
  • SqlAlchemy 连接字符串[重复]

    这个问题在这里已经有答案了 我遇到了非常奇怪的问题 我使用 sqlalchemy 的解决方案无法连接到数据库 这取决于我使用的密码 例如 以下记录工作正常 PWD 123123123 USR test user SQLALCHEMY DAT
  • 修复 OCaml 中的数据类型

    Haskell 中的以下数据类型如何用 OCaml 或 SML 表示 newtype Fix f In f Fix f 我已经在邮件列表上回答了这个问题 https sympa inria fr sympa arc caml list 20
  • R.java 文件实际上做什么以及如何做

    我一直在研究一个简单的 android 教程 在浏览项目文件夹时我发现了这个R java文件输入gen文件夹 当我打开时 我觉得它很乱 first R本身就是一个class it had multiple Inner classes定义在例
  • 如何在格式为“0000-00-00T00:00:00+00:00”的字符串上使用 datetime.strptime?

    由于我的应用程序的情况 我更愿意使用datetime strptime代替dateutil parser 看完之后docs https docs python org 3 library datetime html strftime str
  • 将代码添加到 __init__.py

    我正在研究 django 中的模型系统是如何工作的 我注意到一些我不明白的东西 我知道你创建了一个空的 init pyfile 来指定当前目录是一个包 你可以在其中设置一些变量 init py以便 import 正常工作 但是 django
  • C# 从 URL 下载文件

    谁能告诉我如何从该 URL 下载 C 程序中的文件 http www cryptopro ru products cades plugin get 2 0 http www cryptopro ru products cades plugi
  • 事件溯源基础设施实施

    我在我的应用程序中实现了事件源和 CQRS 模式 我的灵感来自于CQRS 旅程 https msdn microsoft com en us library jj554200 aspx我在哪里下载了示例代码 在那里 我找到了事件源的完整基础
  • 如何将数组作为参数传递给 shell 脚本并获取数组

    我将多个参数传递给 shell 脚本 在该脚本中 我想创建一个从第二个参数到最后一个参数的数组 我可以在下面做到这一点 arg 1 shift while 1 do emailID emailID 1 shift done 我想将此 ema
  • OAuth 2 Google API 刷新令牌为空

    我正在开发一个 Asp NET MVC5 应用程序按照这个谷歌示例代码 https developers google com api client library dotnet guide aaa oauth 我希望应用程序经过身份验证并