Google api 谷歌+;使用google api dotnet客户端插入瞬间

Google api 谷歌+;使用google api dotnet客户端插入瞬间,google-api,google-plus,google-api-dotnet-client,Google Api,Google Plus,Google Api Dotnet Client,我正在尝试使用dotnet客户端在Google+中编写一个活动。问题是我似乎无法正确配置客户端应用程序。根据和,我们需要添加requestvisibleactions参数。我这样做了,但没有成功。我正在使用范围https://www.googleapis.com/auth/plus.login我甚至添加了范围https://www.googleapis.com/auth/plus.moments.write但插入仍不起作用 这是我的请求url的外观: https://accounts.googl

我正在尝试使用dotnet客户端在Google+中编写一个活动。问题是我似乎无法正确配置客户端应用程序。根据和,我们需要添加requestvisibleactions参数。我这样做了,但没有成功。我正在使用范围
https://www.googleapis.com/auth/plus.login
我甚至添加了范围
https://www.googleapis.com/auth/plus.moments.write
但插入仍不起作用

这是我的请求url的外观:

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%26客户端\u id%3D000.apps.googleusercontent.com%26请求\u可见\u操作%3Dhttp://schemas.google.com/AddActivity%26hl%3Den%26from_login%3D1%26as%3D-1fbe06f1c6120f4d<mpl=popup&shdf=CM4LEHF0AGLYZFBHCNR5TG9NB1VYBBOADASSFXROAXJKUGFYDHLEAXNWBGF5TMFTZROHQ2HPA3V0BWWWLEGZKB21HAW4AB0NOAW1DG8MCXIVGHPRQYXJ0EURPC3BSYCLUELGDERUZBVUDBIDbHNvIhTeWybcoJ9pXSeN2t-K8A4SUBSYGBMHQIVAMFNSS_LkjXXZ7bPxilXgjMsQ&scc=1

正如您从那里看到的,有一个
request\u visible\u actions
,我甚至添加了一个没有下划线的操作,以防参数出错(
requestvisibeactions

让我说,我的应用程序正在通过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 =
            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)
        {

        }            `

对于OAuth流,您的请求有两个问题:

  • request\u visible\u操作是传递给OAuth v2服务器的操作(不要传递requestvisibleactions)
  • plus.moments.write是一个不推荐使用的作用域,您只需传入plus.login即可
确保您的项目引用了最新版本的Google+.NET客户端库,如下所示:

我在GitHub上创建了一个项目,在这里显示了完整的服务器端流程:

正如Brettj所说,您应该使用Google+登录按钮,如最新的Google+示例所示:

首先,确保您正在请求您正在编写的所有活动类型。您将知道这是有效的,因为授权对话框将在以“此应用程序希望”开头的文本下方显示“通过谷歌使您的应用程序活动可用,对您可见并:[……]”。我知道你检查了这个,但我90%确定这就是你得到401错误代码的原因。下面的标记显示了如何呈现请求访问添加活动的Google+登录按钮

<div id="gConnect">
<button class="g-signin"
    data-scope="https://www.googleapis.com/auth/plus.login"
    data-requestvisibleactions="http://schemas.google.com/AddActivity"
    data-clientId="YOUR_CLIENT_ID"
    data-accesstype="offline"
    data-callback="onSignInCallback"
    data-theme="dark"
    data-cookiepolicy="single_host_origin">
</button>

注意,为了方便起见,我加入了Google.api.Plus.v1.Data。

啊,就是这么简单!也许不是?我在回答我自己的问题,并因此接受它作为答案(当然,几天后),以便其他有相同问题的人可以得到指导。但我肯定会投票支持格斯的答案,因为它让我找到了代码的修复方法

因此,根据上面所写的@class answer,成功创建一个时刻的关键是添加
request\u visible\u actions
参数。我这样做了,但我的请求仍然失败,这是因为我错过了一件重要的事情。您需要再添加一个参数,即
访问类型
,它应该设置为
脱机
。OAuth请求至少应该如下所示:&request\u visible\u actions=

对于完整和正确的客户端代码,您可以或添加我在下面添加的内容。您应该记住的最重要的事情是为Google API修改
AuthorizationServerDescription
。以下是我的验证器版本:

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;
}
公共静态OAuth2Authenticator CreateAuthenticator(
字符串clientId,字符串clientSecret)
{
if(string.IsNullOrWhiteSpace(clientId))
抛出新ArgumentException(“clientId不能为空”);
if(string.IsNullOrWhiteSpace(clientSecret))
抛出新ArgumentException(“clientSecret不能为空”);
var description=GoogleAuthenticationServer.description;
var uri=description.AuthorizationEndpoint.AbsoluteUri;
//这是一个已经记录在格斯的博客网站
//在谷歌的(https://developers.google.com/+/web/signin/)
//顺便说一句,dotnetclient示例中没有这一点
//您需要了解OAuth和DNOA是如何工作的。
//我已经有了这个,看我原来的帖子,
//我想这会让我开心的。
if(uri.IndexOf(“请求可见动作”)<1)
{
var param=(uri.IndexOf('?')>0)?“&”:“;
description.AuthorizationEndpoint=新Uri(
uri+param+
“请求\u可见\u操作=http://schemas.google.com/AddActivity");
}
//这就是我一直错过的!
//他们忘了告诉我们这件事还是我在什么地方错过了?
uri=description.AuthorizationEndpoint.AbsoluteUri;
if(uri.IndexOf(“脱机”)<1)
{
var param=(uri.IndexOf('?')>0)?“&”:“;
description.AuthorizationEndpoint=
新Uri(Uri+param+“访问类型=脱机”);
}
//注册验证器。
var provider=新的WebServerClient(说明)
{
ClientIdentifier=clientId,
ClientSecret=ClientSecret,
};            
var验证器=
新的OAuth2Authenticator(提供程序,GetAuthorization)
{noaching=true};
返回验证器;
}

没有
access\u type=offline
我的代码永远不会工作,也永远不会工作。现在我想知道为什么?最好有一些解释。

您使用的是Google+Sign-I吗
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;
}