如何为 GoogleWebAuthorizationBroker.AuthorizeAsync 设置 return_uri?
How do I set return_uri for GoogleWebAuthorizationBroker.AuthorizeAsync?
我正在尝试在我的非 MVC .NET Web 应用程序 中使用 Google Calendar API。 (这似乎是一个重要的区别。)
我尝试使用来自 this example at Google and this example at Daimto along with some helpful hints from a number of related posts here 的代码。
我写了下面的方法:
public void GetUserCredential( String userName )
{
String clientId = ConfigurationManager.AppSettings[ "Google.ClientId" ]; //From Google Developer console https://console.developers.google.com
String clientSecret = ConfigurationManager.AppSettings[ "Google.ClientSecret" ]; //From Google Developer console https://console.developers.google.com
String[] scopes = new string[] {
Google.Apis.Calendar.v3.CalendarService.Scope.Calendar
};
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync( new ClientSecrets
{
ClientId = clientId,
ClientSecret = clientSecret
}, scopes, userName, CancellationToken.None, new FileDataStore( "c:\temp" ) ).Result;
// TODO: Replace FileDataStore with DatabaseDataStore
}
问题是,当调用 Google 的 OAuth2 页面时,redirect_uri
一直设置为 http://localhost:<some-random-port>/authorize
。我不知道如何将其设置为其他内容,如以下示例 URL 生成的 AuthorizeAsync
:
https://accounts.google.com/o/oauth2/auth?access_type=offline
&response_type=code
&client_id=********.apps.googleusercontent.com
&redirect_uri=http:%2F%2Flocalhost:40839%2Fauthorize%2F
&scope=https:%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar
Google 以 redirect_uri_mismatch 错误页面响应,消息为:
“请求中的重定向 URI:http://localhost:XXXXX/authorize/ 与已注册的重定向 URI 不匹配”
我只能在 Google 开发者控制台凭据页面中注册这么多重定向 URI。我不倾向于注册 65535 端口,我想在我的网站上使用 /authorize
以外的页面。具体来说,我想在开发过程中使用 http://localhost:888/Pages/GoogleApiRedirect
,但除了我在开发人员控制台中所做的之外,我不知道我应该在哪里设置它。
如何显式设置 redirect_uri
的值?我也愿意接受“这种方法是完全错误的”形式的回应。
编辑:
在过去一天玩过这个之后,我发现通过使用客户端 ID/Client 本地应用程序的秘密而不是 Web 应用程序,我至少可以到达 Google的网络授权页面没有抱怨 redirect_uri_mismatch。这仍然是不可接受的,因为它仍然 returns 到 http://localhost:<some-random-port>/authorize
,这是我的网络应用程序无法控制的。
您可以使用此代码:(来自 http://coderissues.com/questions/27512300/how-to-append-login-hint-usergmail-com-to-googlewebauthorizationbroker 的原创想法)
dsAuthorizationBroker.RedirectUri = "my localhost redirect uri";
UserCredential credential = await dsAuthorizationBroker.AuthorizeAsync(...
dsAuthorizationBroker.cs
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Requests;
using Google.Apis.Util.Store;
namespace OAuth2
{
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 dsAuthorizationCodeFlow(initializer);
return await new AuthorizationCodeInstalledApp(flow,
new LocalServerCodeReceiver())
.AuthorizeAsync(user, taskCancellationToken).ConfigureAwait(false);
}
}
public class dsAuthorizationCodeFlow : GoogleAuthorizationCodeFlow
{
public dsAuthorizationCodeFlow(Initializer initializer)
: base(initializer) { }
public override AuthorizationCodeRequestUrl
CreateAuthorizationCodeRequest(string redirectUri)
{
return base.CreateAuthorizationCodeRequest(dsAuthorizationBroker.RedirectUri);
}
}
}
如果您尝试在 .NET 应用程序 NON-web 服务器应用程序中使用 GoogleWebAuthorizationBroker.AuthorizeAsync,即 C# 控制台应用程序命令行程序,创建 Google OAuth 配置文件(https://console.developers.google.com/apis) 在 select 下面的凭据中。它是隐藏的,如果您不这样做,如果您选择单选按钮 "Other",它必须经过批准过程。 另请注意,仅复制在以下步骤中创建的 JSON 参数的内容并将您的 client_id/secret 替换为网络应用程序版本仍然会失败。为您的 Google API 控制台创建一个新的 OAuth 客户端配置文件。
单击 "HELP ME CHOOSE"
选择您想要的 API 图书馆即(Google 日历 API)
Select"User Data"
"Yeah -NO AUTHORIZATION REQUIRED FILEDS" 即 Javascript & 重定向
现在你有一个未经授权的个人资料
使用"Download JSON"并将其保存到您的应用程序中以在下面的代码中引用。当您查看此文件时,您会注意到一组不同的参数,以告诉代理这是一个应用程序。在此示例中,我正在访问范围日历 API。只需将范围更改为您要访问的 API。
string[] Scopes = { CalendarService.Scope.Calendar }; //requires full scope to get ACL list..
string ApplicationName = "Name Of Your Application In Authorization Screen";
//just reference the namespaces in your using block
using (var stream = new FileStream("other_client_id.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.
string credPath = "other_token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
}
// Create Google Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
//Then your ready to grab data from here using the methods mentioned in Google Calendar API docs
在创建 oAuth 客户端 ID 时选择 "other" 帮助我解决了重定向问题。 (使用 "Web Application" 选项会尝试重定向到一些 url 的随机端口,这很烦人)
现在我的 Gmail API 工作得很好 :)
我正在尝试在我的非 MVC .NET Web 应用程序 中使用 Google Calendar API。 (这似乎是一个重要的区别。)
我尝试使用来自 this example at Google and this example at Daimto along with some helpful hints from a number of related posts here 的代码。
我写了下面的方法:
public void GetUserCredential( String userName )
{
String clientId = ConfigurationManager.AppSettings[ "Google.ClientId" ]; //From Google Developer console https://console.developers.google.com
String clientSecret = ConfigurationManager.AppSettings[ "Google.ClientSecret" ]; //From Google Developer console https://console.developers.google.com
String[] scopes = new string[] {
Google.Apis.Calendar.v3.CalendarService.Scope.Calendar
};
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync( new ClientSecrets
{
ClientId = clientId,
ClientSecret = clientSecret
}, scopes, userName, CancellationToken.None, new FileDataStore( "c:\temp" ) ).Result;
// TODO: Replace FileDataStore with DatabaseDataStore
}
问题是,当调用 Google 的 OAuth2 页面时,redirect_uri
一直设置为 http://localhost:<some-random-port>/authorize
。我不知道如何将其设置为其他内容,如以下示例 URL 生成的 AuthorizeAsync
:
https://accounts.google.com/o/oauth2/auth?access_type=offline
&response_type=code
&client_id=********.apps.googleusercontent.com
&redirect_uri=http:%2F%2Flocalhost:40839%2Fauthorize%2F
&scope=https:%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar
Google 以 redirect_uri_mismatch 错误页面响应,消息为:
“请求中的重定向 URI:http://localhost:XXXXX/authorize/ 与已注册的重定向 URI 不匹配”
我只能在 Google 开发者控制台凭据页面中注册这么多重定向 URI。我不倾向于注册 65535 端口,我想在我的网站上使用 /authorize
以外的页面。具体来说,我想在开发过程中使用 http://localhost:888/Pages/GoogleApiRedirect
,但除了我在开发人员控制台中所做的之外,我不知道我应该在哪里设置它。
如何显式设置 redirect_uri
的值?我也愿意接受“这种方法是完全错误的”形式的回应。
编辑:
在过去一天玩过这个之后,我发现通过使用客户端 ID/Client 本地应用程序的秘密而不是 Web 应用程序,我至少可以到达 Google的网络授权页面没有抱怨 redirect_uri_mismatch。这仍然是不可接受的,因为它仍然 returns 到 http://localhost:<some-random-port>/authorize
,这是我的网络应用程序无法控制的。
您可以使用此代码:(来自 http://coderissues.com/questions/27512300/how-to-append-login-hint-usergmail-com-to-googlewebauthorizationbroker 的原创想法)
dsAuthorizationBroker.RedirectUri = "my localhost redirect uri";
UserCredential credential = await dsAuthorizationBroker.AuthorizeAsync(...
dsAuthorizationBroker.cs
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Requests;
using Google.Apis.Util.Store;
namespace OAuth2
{
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 dsAuthorizationCodeFlow(initializer);
return await new AuthorizationCodeInstalledApp(flow,
new LocalServerCodeReceiver())
.AuthorizeAsync(user, taskCancellationToken).ConfigureAwait(false);
}
}
public class dsAuthorizationCodeFlow : GoogleAuthorizationCodeFlow
{
public dsAuthorizationCodeFlow(Initializer initializer)
: base(initializer) { }
public override AuthorizationCodeRequestUrl
CreateAuthorizationCodeRequest(string redirectUri)
{
return base.CreateAuthorizationCodeRequest(dsAuthorizationBroker.RedirectUri);
}
}
}
如果您尝试在 .NET 应用程序 NON-web 服务器应用程序中使用 GoogleWebAuthorizationBroker.AuthorizeAsync,即 C# 控制台应用程序命令行程序,创建 Google OAuth 配置文件(https://console.developers.google.com/apis) 在 select 下面的凭据中。它是隐藏的,如果您不这样做,如果您选择单选按钮 "Other",它必须经过批准过程。 另请注意,仅复制在以下步骤中创建的 JSON 参数的内容并将您的 client_id/secret 替换为网络应用程序版本仍然会失败。为您的 Google API 控制台创建一个新的 OAuth 客户端配置文件。
单击 "HELP ME CHOOSE"
选择您想要的 API 图书馆即(Google 日历 API) Select"User Data"
"Yeah -NO AUTHORIZATION REQUIRED FILEDS" 即 Javascript & 重定向 现在你有一个未经授权的个人资料
使用"Download JSON"并将其保存到您的应用程序中以在下面的代码中引用。当您查看此文件时,您会注意到一组不同的参数,以告诉代理这是一个应用程序。在此示例中,我正在访问范围日历 API。只需将范围更改为您要访问的 API。
string[] Scopes = { CalendarService.Scope.Calendar }; //requires full scope to get ACL list..
string ApplicationName = "Name Of Your Application In Authorization Screen";
//just reference the namespaces in your using block
using (var stream = new FileStream("other_client_id.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.
string credPath = "other_token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
}
// Create Google Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
//Then your ready to grab data from here using the methods mentioned in Google Calendar API docs
在创建 oAuth 客户端 ID 时选择 "other" 帮助我解决了重定向问题。 (使用 "Web Application" 选项会尝试重定向到一些 url 的随机端口,这很烦人)
现在我的 Gmail API 工作得很好 :)