Reputation: 529
I'm making a program running on Windows desktop. I'm pretty sure I registered the application type as an "Installed application" − does this matter anyway?
I can get an access code from the user and combine that with my client ID and secret to get an access token. I can use this access token to run some example code that requests the user's contacts, but when I try listing their spreadsheets (using example code), it fails: Execution of request failed: https://spreadsheets.google.com/feeds/spreadsheets/private/full
, The remote server returned an error: (401) Unauthorized
I thought the scopes were correct and in terms of the APIs for my program, I've enabled Contacts API, Drive API and Drive SDK (I didn't think I needed this one anyway).
Here's the relevant C# code, thanks in advance if you can explain why the request to list the spreadsheets fails − I've indicated the point where this occurs:
using Google.GData.Client;
using Google.GData.Spreadsheets;
using Google.Contacts;
using Google.GData.Apps;
…
private static OAuth2Parameters googleAuth;
…
string CLIENT_ID = …;
string CLIENT_SECRET = …;
string SCOPE = "https://spreadsheets.google.com/feeds/ https://docs.googleusercontent.com/ https://docs.google.com/feeds/ https://www.google.com/m8/feeds/"; // read, write, create/delete sheets, use contacts
string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
…
googleAuth = new OAuth2Parameters();
googleAuth.ClientId = CLIENT_ID;
googleAuth.ClientSecret = CLIENT_SECRET;
googleAuth.RedirectUri = REDIRECT_URI;
googleAuth.Scope = SCOPE;
googleAuth.ResponseType = "code";
…
string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(googleAuth);
…
googleAuth.AccessCode = PaneManager.googleCode; // read it back from user (PaneManager is UI)
OAuthUtil.GetAccessToken(googleAuth);
…
RunContactsSample(googleAuth); // runs fine
SpreadsheetsService service = new SpreadsheetsService("Ribbon"); // does this name have any relevance?
service.SetAuthenticationToken(googleAuth.AccessToken);
// Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
SpreadsheetQuery query = new SpreadsheetQuery();
SpreadsheetFeed feed = service.Query(query); // this fails
// 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);
}
private static void RunContactsSample(OAuth2Parameters parameters)
{
try
{
RequestSettings settings = new RequestSettings("Ribbon", parameters);
ContactsRequest cr = new ContactsRequest(settings);
Feed<Contact> f = cr.GetContacts();
foreach (Contact c in f.Entries)
{
Console.WriteLine(c.Name.FullName);
}
}
catch (AppsException a)
{
Console.WriteLine("A Google Apps error occurred.");
Console.WriteLine();
Console.WriteLine("Error code: {0}", a.ErrorCode);
Console.WriteLine("Invalid input: {0}", a.InvalidInput);
Console.WriteLine("Reason: {0}", a.Reason);
}
}
Upvotes: 0
Views: 911
Reputation: 8616
Your OAuth is working properly means that you have configured Google apps properly. Similar issue happened to me with the admin SDK, it was related to incorrect SCOPES.
Try this scope (this one does not have "/" at the end .../feeds, not .../feeds/), Detailed example
string SCOPE = "https://spreadsheets.google.com/feeds https://docs.google.com/feeds";
Also use the API explorer to see exact Scope information.
Upvotes: 1
Reputation: 529
It turns out the way to authorise the request wasn't to call SetAuthenticationToken; it's necessary to create a GOAuth2RequestFactory and add that to the service:
SpreadsheetsService service = new SpreadsheetsService("Ribbon");
GOAuth2RequestFactory requestFactory = new GOAuth2RequestFactory(null, "Ribbon", googleAuth);
service.RequestFactory = requestFactory;
I was under the impression that I would be the one calling the factory and hence, wasn't using it since I didn't know how.
Upvotes: 1