使用google-api-dotnet-client插入Google+时刻 [英] Google+ insert moment using google-api-dotnet-client
问题描述
我正在尝试使用dotnet-client在Google+中撰写活动。问题是,我似乎无法正确地获得我的客户端应用程序的配置。根据 Google+登录配置和这是SO问题,我们需要添加requestvisibleactions参数。我做到了,但没有奏效。我使用的范围 https://www.googleapis.com/auth/plus.login
,我甚至添加了范围 https:// www .googleapis.com / auth / plus.moments.write
但插入仍然无效。
这就是我的请求网址:
https://帐户?.google.com / ServiceLogin服务= LSO&安培;被动= 1209600&安培;继续= HTTPS:?//accounts.google.com/o/oauth2/auth范围%3Dhttps://www.googleapis.com/auth/plus.login %2Bhttps://www.googleapis.com/auth/plus.moments.write%26response_type%3Dcode%26redirect_uri%3Dhttp://本地主机/%26state%3D%26requestvisibleactions%3Dhttp://schemas.google.com/AddActivity% 26client_id%3D000.apps.googleusercontent.com%26request_visible_actions%3Dhttp://schemas.google.com/AddActivity%26hl%3Den%26from_login%3D1%26as%3D-1fbe06f1c6120f4d& ltmpl =弹出&安培; SHDF = Cm4LEhF0aGlyZFBhcnR5TG9nb1VybBoADAsSFXRoaXJkUGFydHlEaXNwbGF5TmFtZRoHQ2hpa3V0bwwLEgZkb21haW4aB0NoaWt1dG8MCxIVdGhpcmRQYXJ0eURpc3BsYXlUeXBlGgdERUZBVUxUDBIDbHNvIhTeWybcoJ9pXSeN2t-k8A4SUbfhsygBMhQivAmfNSs_LkjXXZ7bPxilXgjMsQ&安培; SCC = 1
从这里你可以看到有一个 request_visible_actions
,我甚至添加了一个没有下划线的情况下,我得到的参数是错误的( requestvisibleactions
)。
让我说我的应用程序正在通过API成功验证。我可以在通过身份验证后获取用户的个人资料,并且它位于我的应用失败的插入时刻部分。我的插入代码:
var body = new Moment();
var target = new ItemScope();
target.Id = referenceId;
target.Image = image;
target.Type =http://schemas.google.com/AddActivity;
target.Description = description;
target.Name = caption;
body.Target = target;
body.Type =http://schemas.google.com/AddActivity;
var insert =
MomentsResource.InsertRequest(
//这是一个有效的服务实例,因为我使用它来查询用户的配置文件
_plusService,
body,
id,
MomentsResource.Collection.Vault);
瞬间结果=空;
尝试
{
result = insert.Fetch();
}
catch(ThreadAbortException)
{
//用户还没有被认证并且被转发到授权页面。
throw;
}
catch(Google.GoogleApiRequestException requestEx)
{
//这里我得到了401未授权错误
}
catch(Exception ex)
{
}`
嗯就这么简单!也许不会?我正在回答我自己的问题,并因此接受它作为答案(在几天之后),以便引导具有相同问题的其他人。但是我肯定会对Gus的答案进行投票,因为这导致我修复了我的代码。
所以根据上面写的@class回答和在他的博客中解释密钥要成功创建一个时刻,请添加 request_visible_actions
参数。我这样做了,但我的请求仍然失败,这是因为我错过了一件重要的事情。您需要添加一个参数,即 access_type
,并且它应该设置为 offline
code> 即可。 OAuth请求至少应如下所示: https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com & rel =nofollow> http://schemas.google.com/AddActivity&access_type=offline 。
要获得完整且正确的客户端代码,您可以在此处获取Gus的示例或下载整个dotnet客户端库,包括源代码和示例并添加下面添加的内容。您应该记住的最重要的事情是修改Google API的 AuthorizationServerDescription
。这是我的版本验证器:
public static OAuth2Authenticator< WebServerClient> CreateAuthenticator(
我的代码从未工作过,它永远不会工作。现在我想知道为什么?有一些解释是很好的。
string clientId,string clientSecret)
{
if(string.IsNullOrWhiteSpace(clientId))
throw new ArgumentException(clientId can not empty);
if(string.IsNullOrWhiteSpace(clientSecret))
抛出新的ArgumentException(clientSecret不能为空);
var description = GoogleAuthenticationServer.Description;
var uri = description.AuthorizationEndpoint.AbsoluteUri;
//这是在Gus的博客网站
//以及Google的(https://developers.google.com/+/web/signin/)
//这不是以
//的方式在dotnetclient示例中,并且您需要了解OAuth和DNOA如何工作。
//我已经拥有了,请查看我原来的帖子,
//我认为这会让我度过一天。 (uri.IndexOf(request_visible_actions)< 1)
{
var param =(uri.IndexOf('?')> 0)?
if &安培; :?;
description.AuthorizationEndpoint = new Uri(
uri + param +
request_visible_actions = http://schemas.google.com/AddActivity);
}
//这是我一直想念的东西!
//他们忘了告诉我们这件事,还是我错过了这个地方?
uri = description.AuthorizationEndpoint.AbsoluteUri; (uri.IndexOf('offline')< 1)
{
var param =(uri.IndexOf('?')> 0)?
if &安培; :?;
description.AuthorizationEndpoint =
new Uri(uri + param +access_type = offline);
}
//注册认证者。
var provider = new WebServerClient(描述)
{
ClientIdentifier = clientId,
ClientSecret = clientSecret,
};
var authenticator =
new OAuth2Authenticator< WebServerClient>(provider,GetAuthorization)
{NoCaching = true};
返回认证者;
$ / code>I am trying to write an activity in Google+ using the dotnet-client. The issue is that I can't seem to get the configuration of my client app correctly. According to the Google+ Sign-In configuration and this SO question we need to add the requestvisibleactions parameter. I did that but it did not work. I am using the scope
https://www.googleapis.com/auth/plus.login
and I even added the scopehttps://www.googleapis.com/auth/plus.moments.write
but the insert still did not work.This is what my request url looks like:
https://accounts.google.com/ServiceLogin?service=lso&passive=1209600&continue=https://accounts.google.com/o/oauth2/auth?scope%3Dhttps://www.googleapis.com/auth/plus.login%2Bhttps://www.googleapis.com/auth/plus.moments.write%26response_type%3Dcode%26redirect_uri%3Dhttp://localhost/%26state%3D%26requestvisibleactions%3Dhttp://schemas.google.com/AddActivity%26client_id%3D000.apps.googleusercontent.com%26request_visible_actions%3Dhttp://schemas.google.com/AddActivity%26hl%3Den%26from_login%3D1%26as%3D-1fbe06f1c6120f4d<mpl=popup&shdf=Cm4LEhF0aGlyZFBhcnR5TG9nb1VybBoADAsSFXRoaXJkUGFydHlEaXNwbGF5TmFtZRoHQ2hpa3V0bwwLEgZkb21haW4aB0NoaWt1dG8MCxIVdGhpcmRQYXJ0eURpc3BsYXlUeXBlGgdERUZBVUxUDBIDbHNvIhTeWybcoJ9pXSeN2t-k8A4SUbfhsygBMhQivAmfNSs_LkjXXZ7bPxilXgjMsQ&scc=1
As you can see from there that there is a
request_visible_actions
and I even added one that has no underscore in case I got the parameter wrong (requestvisibleactions
).Let me say that my app is being authenticated successfully by the API. I can get the user's profile after being authenticated and it is on the "insert moment" part that my app fails. My insert code:
var body = new Moment(); var target = new ItemScope(); target.Id = referenceId; target.Image = image; target.Type = "http://schemas.google.com/AddActivity"; target.Description = description; target.Name = caption; body.Target = target; body.Type = "http://schemas.google.com/AddActivity"; var insert = new MomentsResource.InsertRequest( // this is a valid service instance as I am using this to query the user's profile _plusService, body, id, MomentsResource.Collection.Vault); Moment result = null; try { result = insert.Fetch(); } catch (ThreadAbortException) { // User was not yet authenticated and is being forwarded to the authorization page. throw; } catch (Google.GoogleApiRequestException requestEx) { // here I get a 401 Unauthorized error } catch (Exception ex) { } `
解决方案Ah it's that simple! Maybe not? I am answering my own question and consequently accept it as the answer (after a few days of course) so others having the same issue may be guided. But I will definitely up-vote Gus' answer for it led me to the fix for my code.
So according to @class answer written above and as explained on his blog the key to successfully creating a moment is adding the
request_visible_actions
parameter. I did that but my request still failed and it is because I was missing an important thing. You need to add one more parameter and that is theaccess_type
and it should be set tooffline
. The OAuth request, at a minimum, should look like: https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/plus.login&response_type=code&redirect_uri=http://localhost/&request_visible_actions=http://schemas.google.com/AddActivity&access_type=offline.For the complete and correct client code you can get Gus' example here or download the entire dotnet client library including the source and sample and add what I added below. The most important thing that you should remember is modifying your
AuthorizationServerDescription
for the Google API. Here's my version of the authenticator:public static OAuth2Authenticator<WebServerClient> CreateAuthenticator( string clientId, string clientSecret) { if (string.IsNullOrWhiteSpace(clientId)) throw new ArgumentException("clientId cannot be empty"); if (string.IsNullOrWhiteSpace(clientSecret)) throw new ArgumentException("clientSecret cannot be empty"); var description = GoogleAuthenticationServer.Description; var uri = description.AuthorizationEndpoint.AbsoluteUri; // This is the one that has been documented on Gus' blog site // and over at Google's (https://developers.google.com/+/web/signin/) // This is not in the dotnetclient sample by the way // and you need to understand how OAuth and DNOA works. // I had this already, see my original post, // I thought it will make my day. if (uri.IndexOf("request_visible_actions") < 1) { var param = (uri.IndexOf('?') > 0) ? "&" : "?"; description.AuthorizationEndpoint = new Uri( uri + param + "request_visible_actions=http://schemas.google.com/AddActivity"); } // This is what I have been missing! // They forgot to tell us about this or did I just miss this somewhere? uri = description.AuthorizationEndpoint.AbsoluteUri; if (uri.IndexOf("offline") < 1) { var param = (uri.IndexOf('?') > 0) ? "&" : "?"; description.AuthorizationEndpoint = new Uri(uri + param + "access_type=offline"); } // Register the authenticator. var provider = new WebServerClient(description) { ClientIdentifier = clientId, ClientSecret = clientSecret, }; var authenticator = new OAuth2Authenticator<WebServerClient>(provider, GetAuthorization) { NoCaching = true }; return authenticator; }
Without the
access_type=offline
my code never worked and it will never work. Now I wonder why? It would be good to have some explanation.这篇关于使用google-api-dotnet-client插入Google+时刻的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!