1

dotnet-client を使用して Google+ でアクティビティを作成しようとしています。問題は、クライアント アプリの構成を正しく取得できないように見えることです。Google+ サインインの構成この SO の質問に従って、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%26client_id%3D000.apps.googleusercontent.com%26request_visible_actions%3Dhttp://schemas.google.com/AddActivity%26hl%3Den%26from_login%3D1%26as%3D-1fbe06f1c6120f4d&ltmpl=popup&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 =
            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)
        {

        }            `
4

2 に答える 2

2

OAuth フローの場合、リクエストには 2 つの問題があります。

  • request_visible_actions は、OAuth v2 サーバーに渡されるものです (requestvisibleactions は渡さないでください)。
  • plus.moments.write は非推奨のスコープです。plus.login のみを渡す必要があります。

プロジェクトが次の場所から最新バージョンの Google+ .NET クライアント ライブラリを参照していることを確認してください。

https://developers.google.com/resources/api-libraries/download/stable/plus/v1/csharp

ここにサーバー側の完全なフローを示すプロジェクトを GitHub で作成しました。

https://github.com/gguuss/gplus_csharp_ssflow

Brettj が言ったように、ここの最新の Google+ サンプルで示されているように、Google+ サインイン ボタンを使用する必要があります。

https://github.com/googleplus/gplus-quickstart-csharp

まず、作成しているすべてのアクティビティ タイプをリクエストしていることを確認します。これが機能していることは、承認ダイアログの「このアプリは次のことを望んでいます」で始まるテキストの下に「Google 経由でアプリのアクティビティを利用できるようにし、あなたに表示して [...]」と表示されるためです。これをチェックしたことは知っていますが、これが 401 エラー コードを受け取っている理由であると 90% 確信しています。次のマークアップは、追加アクティビティへのアクセスを要求する 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>

data-requestvisibleactions に正しいアクティビティ タイプが設定された PlusService オブジェクトがあると仮定すると、コピーして貼り付けて動作を確認できる次のコードは、.NET クライアントを使用した書き込みの瞬間を簡潔に示しており、動作することがテストされています。 :

Moment body = new Moment();
ItemScope target = new ItemScope();

target.Id = "replacewithuniqueforaddtarget";
target.Image = "http://www.google.com/s2/static/images/GoogleyEyes.png";
target.Type = "";
target.Description = "The description for the activity";
target.Name = "An example of add activity";

body.Target = target;
body.Type = "http://schemas.google.com/AddActivity";

MomentsResource.InsertRequest insert =
    new MomentsResource.InsertRequest(
        _plusService,
        body,
        "me",
        MomentsResource.Collection.Vault);
Moment wrote = insert.Fetch();

便宜上、Google.Apis.Plus.v1.Data を含めていることに注意してください。

于 2013-03-08T02:30:17.517 に答える
1

ああ、それはとても簡単です!そうでないかもしれない?私は自分の質問に答えており、その結果、(もちろん数日後)それを答えとして受け入れるので、同じ問題を抱えている他の人が導かれるかもしれません. しかし、Gusの答えに賛成票を投じることは間違いなく、コードの修正につながりました。

したがって、上記の @class の回答と彼のブログで説明されているように、瞬間をうまく作成するための鍵はrequest_visible_actionsパラメーターを追加することです。私はそれをしましたが、私の要求はまだ失敗しました.それは私が重要なことを見逃していたからです. パラメータをもう 1 つ追加する必要があります。access_typeそれは であり、 に設定する必要がありますoffline。OAuth リクエストは、少なくとも次のようになります: 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 .

完全で正しいクライアント コードについては、ここで Gus の例を入手する、ソースとサンプルを含む dotnet クライアント ライブラリ全体をダウンロードして、以下に追加したものを追加してください。覚えておくべき最も重要なことはAuthorizationServerDescription、Google API 用に変更することです。オーセンティケーターの私のバージョンは次のとおりです。

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;
}

私のコードがなければ、access_type=offline決して機能せず、機能しません。なぜだろう?説明があればいいですね。

于 2013-03-08T07:48:45.917 に答える