如何让 Google 的 OAuth API 自动刷新令牌?
How to get Google's OAuth API to refresh token automatically?
海牙都!我有以下代码设置我的 Google API:
// Open the FileStream to the related file.
using FileStream stream = new("Credentials.json", FileMode.Open, FileAccess.Read);
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
new[] { SheetsService.Scope.Spreadsheets, YouTubeService.Scope.YoutubeReadonly },
"admin",
CancellationToken.None,
new FileDataStore("Token", true),
new PromptCodeReceiver()
);
// Create Google Sheets API service.
builder.Services.AddSingleton(new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = name,
}));
// Create Youtube API service.
builder.Services.AddSingleton(new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = name,
}));
使用此代码,我的所有服务都已正确注入到我正在使用的服务提供商中。然而,在 ASP.Net 网站启动 7 天后似乎没有刷新令牌,即使我的令牌文件有一个刷新令牌。正如我想象的那样,这是因为 OAuth 令牌只能使用 7 天。
那么,如何让 Google 的 API 自动刷新我的令牌?由于这是一个网站,它需要长时间在线而不因令牌过期而宕机。
是想让 ASP.NET 应用程序访问 Youtube 和表格...
- 代表最终用户或
- 代表自己(不涉及最终用户?
在 (1) 的情况下,使用 GoogleWebAuthorizationBroker
启动 OAuth 授权流程是正确的方法,但您可能不应该永久存储刷新令牌。要么仅在最终用户会话期间存储它,要么根本不存储它并在每次访问令牌过期时触发新的 OAuth 授权流程。
在 (2) 的情况下,您应该使用服务帐户和 load credentials by using GoogleCredentials.GetApplicationDefaultAsync()
. If the app runs on Google Cloud, attach a service account to the underlying compute resource; if it's running elsewhere you can use Workload identity federation or service account keys。
如果您的应用仍在测试中,刷新令牌将在 7 天后过期。要让它们过期更长时间,您需要将您的应用程序设置为生产环境,并可能对其进行验证。
A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
网络应用与安装的应用
我很惊讶你的代码在网站上运行。
GoogleWebAuthorizationBroker.AuthorizeAsync 适用于已安装的应用程序。它不适用于托管在网站上的 Asp .net。它不起作用的原因是它会导致同意浏览器在代码所在的机器上打开 运行。这将在开发中起作用,但一旦您尝试将其托管在网络服务器上,它就无法工作,因为服务器无法生成本地网络浏览器。
您应该关注 Web applications (ASP.NET Core 3)
哪个会用到依赖注入
public void ConfigureServices(IServiceCollection services)
{
...
// This configures Google.Apis.Auth.AspNetCore3 for use in this app.
services
.AddAuthentication(o =>
{
// This forces challenge results to be handled by Google OpenID Handler, so there's no
// need to add an AccountController that emits challenges for Login.
o.DefaultChallengeScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
// This forces forbid results to be handled by Google OpenID Handler, which checks if
// extra scopes are required and does automatic incremental auth.
o.DefaultForbidScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
// Default scheme that will handle everything else.
// Once a user is authenticated, the OAuth2 token info is stored in cookies.
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogleOpenIdConnect(options =>
{
options.ClientId = {YOUR_CLIENT_ID};
options.ClientSecret = {YOUR_CLIENT_SECRET};
});
}
您无需担心刷新访问令牌,图书馆会为您处理。
海牙都!我有以下代码设置我的 Google API:
// Open the FileStream to the related file.
using FileStream stream = new("Credentials.json", FileMode.Open, FileAccess.Read);
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
new[] { SheetsService.Scope.Spreadsheets, YouTubeService.Scope.YoutubeReadonly },
"admin",
CancellationToken.None,
new FileDataStore("Token", true),
new PromptCodeReceiver()
);
// Create Google Sheets API service.
builder.Services.AddSingleton(new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = name,
}));
// Create Youtube API service.
builder.Services.AddSingleton(new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = name,
}));
使用此代码,我的所有服务都已正确注入到我正在使用的服务提供商中。然而,在 ASP.Net 网站启动 7 天后似乎没有刷新令牌,即使我的令牌文件有一个刷新令牌。正如我想象的那样,这是因为 OAuth 令牌只能使用 7 天。
那么,如何让 Google 的 API 自动刷新我的令牌?由于这是一个网站,它需要长时间在线而不因令牌过期而宕机。
是想让 ASP.NET 应用程序访问 Youtube 和表格...
- 代表最终用户或
- 代表自己(不涉及最终用户?
在 (1) 的情况下,使用 GoogleWebAuthorizationBroker
启动 OAuth 授权流程是正确的方法,但您可能不应该永久存储刷新令牌。要么仅在最终用户会话期间存储它,要么根本不存储它并在每次访问令牌过期时触发新的 OAuth 授权流程。
在 (2) 的情况下,您应该使用服务帐户和 load credentials by using GoogleCredentials.GetApplicationDefaultAsync()
. If the app runs on Google Cloud, attach a service account to the underlying compute resource; if it's running elsewhere you can use Workload identity federation or service account keys。
如果您的应用仍在测试中,刷新令牌将在 7 天后过期。要让它们过期更长时间,您需要将您的应用程序设置为生产环境,并可能对其进行验证。
A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
网络应用与安装的应用
我很惊讶你的代码在网站上运行。 GoogleWebAuthorizationBroker.AuthorizeAsync 适用于已安装的应用程序。它不适用于托管在网站上的 Asp .net。它不起作用的原因是它会导致同意浏览器在代码所在的机器上打开 运行。这将在开发中起作用,但一旦您尝试将其托管在网络服务器上,它就无法工作,因为服务器无法生成本地网络浏览器。
您应该关注 Web applications (ASP.NET Core 3)
哪个会用到依赖注入
public void ConfigureServices(IServiceCollection services)
{
...
// This configures Google.Apis.Auth.AspNetCore3 for use in this app.
services
.AddAuthentication(o =>
{
// This forces challenge results to be handled by Google OpenID Handler, so there's no
// need to add an AccountController that emits challenges for Login.
o.DefaultChallengeScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
// This forces forbid results to be handled by Google OpenID Handler, which checks if
// extra scopes are required and does automatic incremental auth.
o.DefaultForbidScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
// Default scheme that will handle everything else.
// Once a user is authenticated, the OAuth2 token info is stored in cookies.
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogleOpenIdConnect(options =>
{
options.ClientId = {YOUR_CLIENT_ID};
options.ClientSecret = {YOUR_CLIENT_SECRET};
});
}
您无需担心刷新访问令牌,图书馆会为您处理。