尝试在Google云端硬盘上验证和访问电子表格时,我突然开始出现以下异常:
未处理的异常:Google.GData.Client.GDataRequestException: 执行aut hentication请求意外返回 结果:404 at Google.GData.Client.Utilities.getAuthException(TokenCollection tokens, Htt pWebResponse回复) 在Google.GData.Client.Utilities.QueryClientLoginToken(GDataCredentials gc,S tring serviceName,String applicationName,Boolean fUseKeepAlive,IWebProxy prox yServer,Uri clientLoginHandler) 在Google.GData.Client.GDataGAuthRequest.QueryAuthToken(GDataCredentials GC) at Google.GData.Client.GDataGAuthRequest.EnsureCredentials() at Google.GData.Client.GDataRequest.EnsureWebRequest() at Google.GData.Client.GDataGAuthRequest.EnsureWebRequest() 在Google.GData.Client.GDataRequest.Execute() at Google.GData.Client.GDataGAuthRequest.Execute(Int32 retryCounter) 在Google.GData.Client.GDataGAuthRequest.Execute() 在Google.GData.Client.Service.Query(Uri queryUri,DateTime ifModifiedSince,String etag,Int64& contentLength) 在Google.GData.Client.Service.Query(FeedQuery feedQuery) 在Google.GData.Documents.DocumentsService.Query(DocumentsListQuery feedQuery) 在GoogleLogger.GoogleService.getLastXECLogRows(String folderName,String fileName,Int32 rows)
这是代码已经运行了两年没有任何问题。我首先想到我可能已经失去了对我的生产系统的访问权限,但谷歌驱动器在我的网络浏览器中加载得很好。在其他几个系统上尝试过它并且得到了相同的结果。
他们今天在Google API中有所改变吗?这不是巧合!
答案 0 :(得分:33)
Google已停用旧的身份验证API。应该使用OAuth 2.0。
我花了太多时间来弄清楚如何使用较新的Auth API和较旧的GData API从互联网上随处获取信息。 我决定与屏幕截图分享所有细节,以节省您的时间。
点击Create Project
按钮
API & Auth
> Credentials
并点击Create new Client ID
按钮。它会自动为您创建JSON密钥 - 忽略它。
Generate new P12 key
Build Action
和Copy to Output Directory
。
使用Nuget安装Google API Auth。在程序包管理器控制台中键入以下内容
Install-Package Google.Apis.Auth
在Google电子表格中为此用户授予适当的权限。
使用以下代码查询电子表格。在下面的代码中替换电子邮件和Google电子表格URL地址。
const string ServiceAccountEmail = "452351479-q41ce1720qd9l94s8847mhc0toao1fed@developer.gserviceaccount.com";
var certificate = new X509Certificate2("Key.p12", "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccountCredentialInitializer =
new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { "https://spreadsheets.google.com/feeds" }
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Result)
throw new InvalidOperationException("Access token request failed.");
var requestFactory = new GDataRequestFactory(null);
requestFactory.CustomHeaders.Add("Authorization: Bearer " + credential.Token.AccessToken);
var service = new SpreadsheetsService(null) { RequestFactory = requestFactory };
var query = new ListQuery("https://spreadsheets.google.com/feeds/list/0ApZkobM61WIrdGRYshh345523VNsLWc/1/private/full");
var feed = service.Query(query);
var rows = feed.Entries
.Cast<ListEntry>()
.Select(arg =>
new
{
Field0 = arg.Elements[0].Value,
Field1 = arg.Elements[1].Value
})
.ToList();
答案 1 :(得分:5)
我通过使用带有oAuth2.0的服务帐户的此解决方案设法解决了这个问题 Accessing older GData APIs (Spreadsheet API) using OAuth 2 and a service account
解决方案: 1.在https://console.developers.google.com/project
中创建项目和Google服务帐户代码:
using System.Security.Cryptography.X509Certificates;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Spreadsheets;
using Google.Apis.Auth.OAuth2;
string keyFilePath = @"C:\key.p12"; // found in developer console
string serviceAccountEmail = "youraccount@developer.gserviceaccount.com"; // found in developer console
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail) //create credential using certificate
{
Scopes = new[] { "https://spreadsheets.google.com/feeds/" } //this scopr is for spreadsheets, check google scope FAQ for others
}.FromCertificate(certificate));
credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait(); //request token
var requestFactory = new GDataRequestFactory("Some Name");
requestFactory.CustomHeaders.Add(string.Format("Authorization: Bearer {0}", credential.Token.AccessToken));
SpreadsheetsService myService = new SpreadsheetsService("You App Name"); //create your old service
myService.RequestFactory = requestFactory; //add new request factory to your old service
SpreadsheetQuery query = new SpreadsheetQuery(); //do the job as you done it before
SpreadsheetFeed feed = myService.Query(query);
答案 2 :(得分:4)
好吧,我明白了。分步说明如下 - 另请参阅下面提供的代码。仅供参考,这是在.Net 3.5中运行的,与以前提供的解决方案不同,没有新的依赖关系。你应该立即启动并运行。
如果您还没有创建OAuth 2.0凭据 - 我假设您已经知道如何获取这些凭据,而不是在这里:
a)登录您的Google开发者控制台:http://console.developers.google.com b)创建一个项目 c)创建您的凭据 - 使用已安装的应用程序&#39; d)添加您需要的API - 我认为绝对需要Drive API。我还添加了Drive SDK以防万一。
将以下代码复制到VS中,并使用客户端密钥和密钥编辑第一个Main()方法。
运行应用并复制新的访问令牌和刷新令牌。将这些和您剩余的凭据放入下面的第二个Main()方法。
您现在应该能够运行第二个Main()方法(只需反转命名)。从现在开始,这将是你所需要的 - 无需重新运行第一个Main()方法。
BTW,下面的第一个Main()方法可以在这里找到:https://developers.google.com/google-apps/spreadsheets/authorize
然而,我确实添加了丢失的令牌类型以及访问类型。这些都是必需的,所以请使用下面的代码:using System;
using Google.GData.Client;
using Google.GData.Spreadsheets;
using Google.GData.Documents;
using System.Configuration;
using System.Collections.Specialized;
namespace GoogleSpreadsheet
{
class GoogleOAutho2
{
private static String folderName = "crazy.ivan";
static void Main(string[] args)
{
////////////////////////////////////////////////////////////////////////////
// STEP 1: Configure how to perform OAuth 2.0
////////////////////////////////////////////////////////////////////////////
// TODO: Update the following information with that obtained from
// https://code.google.com/apis/console. After registering
// your application, these will be provided for you.
string CLIENT_ID = "your_client_id";
// This is the OAuth 2.0 Client Secret retrieved
// above. Be sure to store this value securely. Leaking this
// value would enable others to act on behalf of your application!
string CLIENT_SECRET = "your_secret_key"
// Space separated list of scopes for which to request access.
string SCOPE = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds https://docs.google.com/feeds";
// This is the Redirect URI for installed applications.
// If you are building a web application, you have to set your
// Redirect URI at https://code.google.com/apis/console.
string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
string TOKEN_TYPE = "refresh";
////////////////////////////////////////////////////////////////////////////
// STEP 2: Set up the OAuth 2.0 object
////////////////////////////////////////////////////////////////////////////
// OAuth2Parameters holds all the parameters related to OAuth 2.0.
OAuth2Parameters parameters = new OAuth2Parameters();
// Set your OAuth 2.0 Client Id (which you can register at
// https://code.google.com/apis/console).
parameters.ClientId = CLIENT_ID;
// Set your OAuth 2.0 Client Secret, which can be obtained at
// https://code.google.com/apis/console.
parameters.ClientSecret = CLIENT_SECRET;
// Set your Redirect URI, which can be registered at
// https://code.google.com/apis/console.
parameters.RedirectUri = REDIRECT_URI;
////////////////////////////////////////////////////////////////////////////
// STEP 3: Get the Authorization URL
////////////////////////////////////////////////////////////////////////////
// Set the scope for this particular service.
parameters.Scope = SCOPE;
parameters.AccessType = "offline"; // IMPORTANT and was missing in the original
parameters.TokenType = TOKEN_TYPE; // IMPORTANT and was missing in the original
// Get the authorization url. The user of your application must visit
// this url in order to authorize with Google. If you are building a
// browser-based application, you can redirect the user to the authorization
// url.
string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
Console.WriteLine(authorizationUrl);
Console.WriteLine("Please visit the URL above to authorize your OAuth "
+ "request token. Once that is complete, type in your access code to "
+ "continue...");
parameters.AccessCode = Console.ReadLine();
////////////////////////////////////////////////////////////////////////////
// STEP 4: Get the Access Token
////////////////////////////////////////////////////////////////////////////
// Once the user authorizes with Google, the request token can be exchanged
// for a long-lived access token. If you are building a browser-based
// application, you should parse the incoming request token from the url and
// set it in OAuthParameters before calling GetAccessToken().
OAuthUtil.GetAccessToken(parameters);
string accessToken = parameters.AccessToken;
string refreshToken = parameters.RefreshToken;
Console.WriteLine("OAuth Access Token: " + accessToken + "\n");
Console.WriteLine("OAuth Refresh Token: " + refreshToken + "\n");
////////////////////////////////////////////////////////////////////////////
// STEP 5: Make an OAuth authorized request to Google
////////////////////////////////////////////////////////////////////////////
// Initialize the variables needed to make the request
GOAuth2RequestFactory requestFactory =
new GOAuth2RequestFactory(null, "MySpreadsheetIntegration-v1", parameters);
SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
service.RequestFactory = requestFactory;
// Make the request to Google
// See other portions of this guide for code to put here...
// Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
Google.GData.Spreadsheets.SpreadsheetQuery query = new Google.GData.Spreadsheets.SpreadsheetQuery();
// Make a request to the API and get all spreadsheets.
SpreadsheetFeed feed = service.Query(query);
// Iterate through all of the spreadsheets returned
foreach (SpreadsheetEntry entry in feed.Entries)
{
// Print the title of this spreadsheet to the screen
Console.WriteLine(entry.Title.Text);
}
Console.ReadLine();
}
// once you copied your access and refresh tokens
// then you can run this method directly from now on...
static void MainX(string[] args)
{
GOAuth2RequestFactory requestFactory = RefreshAuthenticate();
SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
service.RequestFactory = requestFactory;
// Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
Google.GData.Spreadsheets.SpreadsheetQuery query = new Google.GData.Spreadsheets.SpreadsheetQuery();
// Make a request to the API and get all spreadsheets.
SpreadsheetFeed feed = service.Query(query);
// Iterate through all of the spreadsheets returned
foreach (SpreadsheetEntry entry in feed.Entries)
{
// Print the title of this spreadsheet to the screen
Console.WriteLine(entry.Title.Text);
}
Console.ReadLine();
public static GOAuth2RequestFactory RefreshAuthenticate() {
OAuth2Parameters parameters = new OAuth2Parameters(){
RefreshToken = "the_refresh_token_you_copied_from_the_CLI_running_the_first_method";
AccessToken = "the_access_token_you_copied_from_the_CLI_running_the_first_method";
ClientId = "your_client_id";
ClientSecret = "your_dirty_little_secret";
Scope = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds",
AccessType = "offline",
TokenType = "refresh"
};
string authUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
return new GOAuth2RequestFactory(null, "evilspeculator", parameters);
}
}
}
希望对你们有用 - 祝你好运!
答案 3 :(得分:0)
Andrew我想知道你是如何得到google.apis.auth.oauth2 dll的。我试图暗示你的修复,我无法找到安装库的正确方法。
在我有这个部分之后,我觉得我可能能够让它工作。