【问题标题】:Google OAuth2: When and how to use refresh tokenGoogle OAuth2:何时以及如何使用刷新令牌
【发布时间】:2023-04-02 13:50:01
【问题描述】:

我有一个已安装的 c# 应用程序,其代码可以获取授权代码并将其交换为访问令牌。我正在存储刷新令牌。我知道在某些时候我需要使用它来获取新的访问令牌。假设我定期调用以下方法来监控已与我的云端硬盘帐户共享的文件。

   /// <summary>
   /// Retrieve a list of File resources.
   /// </summary>
   /// <param name="service">Drive API service instance.</param>
   /// <returns>List of File resources.</returns>
   public static List<File> retrieveAllFiles(DriveService service) {
      List<File> result = new List<File>();
      FilesResource.ListRequest request = service.Files.List();
      request.Q = "sharedWithMe and trashed=false";
      do {
         try {
            FileList files = request.Fetch();

            result.AddRange(files.Items);
            request.PageToken = files.NextPageToken;
         } catch (Exception e) {
            Console.WriteLine("An error occurred: " + e.Message);
            request.PageToken = null;
         }
      } while (!String.IsNullOrEmpty(request.PageToken));
      return result;
   }
}

我假设在某些时候对 service.Files.List() 的调用会失败。我怎么知道它由于访问令牌过期而失败,以及使用刷新令牌的代码是什么?我已经有一些从here 收集的代码(如下)用于使用刷新令牌。访问令牌过期时会调用这个方法吗?

    private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
   {
      // If we already have a RefreshToken, use that
      if (!string.IsNullOrEmpty(RefreshToken))
      {
         state.RefreshToken = RefreshToken;
         if (arg.RefreshToken(state)) {
            mTextBox.Text = "RF: " + RefreshToken;
            return state;
         }
      }
      // authCode is a TextBox on the form
      var result = arg.ProcessUserAuthorization(mTextBox.Text, state);
      RefreshToken = state.RefreshToken;
      return result;
   }

【问题讨论】:

    标签: c# google-oauth


    【解决方案1】:

    访问令牌将在 1 小时后过期 - 在那之后,当您调用 Google API 时,您将开始收到“401 Invalid Credentials”错误。

    我不熟悉 .NET Google API 客户端库 - Java 和 Python 库会在发生这种情况时自动请求新的访问令牌,具体取决于您创建 DriveService 对象的方式。我希望 .NET 库具有类似的语义。

    【讨论】:

    • 访问令牌通常会在 1 小时后过期,但不要硬编码此值。始终使用 expires_in 参数,仅作为提示。
    • 那么当我在retrieveAllFiles 中捕获异常时,我会在哪里放置代码以刷新令牌?你能说得更清楚些吗?
    • 您究竟是如何创建 DriveService 对象的?同样,不熟悉 .NET Google 库,但 Java/Python 库的模式是:(1)创建一个 Credentials 对象(包含刷新令牌),(2)您使用 Credentials 对象创建一个授权的HTTP 对象,即发出 HTTP 请求的对象,该对象负责捕获 401 并为您获取新的访问令牌,然后 (3) 创建一个服务对象(如 DriveService)并将该 HTTP 对象传递给它。 .NET 库可能类似 - DriveService 对象可能会为您处理这个问题。
    【解决方案2】:

    如果有人在刷新 AccessToken 时仍然遇到问题,也许这可以帮助您找到解决方案:

                Google.GData.Client.RequestSettings settings = new RequestSettings("<AppName>");
                Google.GData.Client.OAuth2Parameters parameters = new OAuth2Parameters()
                {
                    ClientId = "<YourClientId>",
                    ClientSecret = "<YourClientSecret>",
                    AccessToken = "<OldAccessToken>", //really necessary?
    
                    RedirectUri = "urn:ietf:wg:oauth:2.0:oob",
                    RefreshToken = "<YourRefreshToken>",
                    AccessType = "offline",
                    TokenType = "refresh",
                    Scope = "https://www.google.com/m8/feeds/" //Change to needed scopes, I used this for ContactAPI
                };
                try
                {
                    Google.GData.Client.OAuthUtil.RefreshAccessToken(parameters);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
    

    【讨论】:

      【解决方案3】:

      何时使用刷新令牌:

      据我了解,当您不希望每次启动应用时都对其进行身份验证时,您会使用刷新令牌。这对于应用程序开发期间的调试非常有用(因为手动身份验证会在一段时间后变得烦人)。

      如何使用刷新令牌:

      在最基本的意义上:

      public static GOAuth2RequestFactory RefreshAuthenticate(){
          OAuth2Parameters parameters = new OAuth2Parameters(){
              RefreshToken = "<YourRefreshToken>",
              AccessToken = "<AnyOfYourPreviousAccessTokens>",
              ClientId = "<YourClientID>",
              ClientSecret = "<YourClientSecret>",
              Scope = "https://spreadsheets.google.com/feeds https://docs.google.com/feeds",
              AccessType = "offline",
              TokenType = "refresh"
          };
          string authUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
          return new GOAuth2RequestFactory(null, "<YourApplicationName>", parameters);
      }
      

      您可以在其他带有服务的代码中使用此方法,可能像这样

      GOAuth2RequestFactory requestFactory = RefreshAuthenticate();
      SpreadsheetsService service = new SpreadsheetsService("<YourApplicationName>");
      service.RequestFactory = requestFactory;
      

      希望这会有所帮助!

      【讨论】:

        【解决方案4】:

        花了两天时间研究如何使用刷新令牌来使用和更新访问令牌。我的答案在这里发布在另一个线程中:

        How Google API V 3.0 .Net library and Google OAuth2 Handling refresh token

        【讨论】:

          猜你喜欢
          • 2018-04-07
          • 1970-01-01
          • 2018-02-27
          • 1970-01-01
          • 1970-01-01
          • 2017-05-29
          • 2016-08-03
          • 2018-06-22
          • 2013-10-01
          相关资源
          最近更新 更多