51

私は一日中良い解決策を探していましたが、Google は急速に進化しているため、機能するものを見つけることができません。私がやりたいことは、ユーザーが情報を表示するためにログインする必要がある管理セクションを持つ Web アプリがあることです。このセクションでは、特定の URL のページビューなど、GA からのデータを表示したいと思います。私が表示しているのはユーザー情報ではなく、Google アナリティクスのユーザーなので、渡す情報 (ユーザー名/パスワードまたは APIKey) を接続したいのですが、方法がわかりません。私が見つけたすべてのサンプルは OAuth2 を使用しています (私が理解している場合は、訪問者に Google を使用してログインするように求めます)。

これまでに見つけたもの:

多分私はただ疲れていて、明日は簡単に解決策を見つけることができるでしょうが、今は助けが必要です!

ありがとう

4

7 に答える 7

31

私は多くの検索を行い、最終的に複数の場所からコードを検索してから、独自のインターフェイスをラップして、次の解決策を思いつきました。人々がコード全体をここに貼り付けるかどうかはわかりませんが、他の人の時間を節約しないのはなぜだと思います:)

前提条件として、Google.GData.Client と google.gdata.analytics パッケージ/dll をインストールする必要があります。

これは、作業を行うメイン クラスです。

namespace Utilities.Google
{
    public class Analytics
    {
        private readonly String ClientUserName;
        private readonly String ClientPassword;
        private readonly String TableID;
        private AnalyticsService analyticsService;

        public Analytics(string user, string password, string table)
        {
            this.ClientUserName = user;
            this.ClientPassword = password;
            this.TableID = table;

            // Configure GA API.
            analyticsService = new AnalyticsService("gaExportAPI_acctSample_v2.0");
            // Client Login Authorization.
            analyticsService.setUserCredentials(ClientUserName, ClientPassword);
        }

        /// <summary>
        /// Get the page views for a particular page path
        /// </summary>
        /// <param name="pagePath"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="isPathAbsolute">make this false if the pagePath is a regular expression</param>
        /// <returns></returns>
        public int GetPageViewsForPagePath(string pagePath, DateTime startDate, DateTime endDate, bool isPathAbsolute = true)
        {
            int output = 0;

            // GA Data Feed query uri.
            String baseUrl = "https://www.google.com/analytics/feeds/data";

            DataQuery query = new DataQuery(baseUrl);
            query.Ids = TableID;
            //query.Dimensions = "ga:source,ga:medium";
            query.Metrics = "ga:pageviews";
            //query.Segment = "gaid::-11";
            var filterPrefix = isPathAbsolute ? "ga:pagepath==" : "ga:pagepath=~";
            query.Filters = filterPrefix + pagePath;
            //query.Sort = "-ga:visits";
            //query.NumberToRetrieve = 5;
            query.GAStartDate = startDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
            query.GAEndDate = endDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
            Uri url = query.Uri;
            DataFeed feed = analyticsService.Query(query);
            output = Int32.Parse(feed.Aggregates.Metrics[0].Value);

            return output;
        }

        public Dictionary<string, int> PageViewCounts(string pagePathRegEx, DateTime startDate, DateTime endDate)
        {
            // GA Data Feed query uri.
            String baseUrl = "https://www.google.com/analytics/feeds/data";

            DataQuery query = new DataQuery(baseUrl);
            query.Ids = TableID;
            query.Dimensions = "ga:pagePath";
            query.Metrics = "ga:pageviews";
            //query.Segment = "gaid::-11";
            var filterPrefix = "ga:pagepath=~";
            query.Filters = filterPrefix + pagePathRegEx;
            //query.Sort = "-ga:visits";
            //query.NumberToRetrieve = 5;
            query.GAStartDate = startDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
            query.GAEndDate = endDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
            Uri url = query.Uri;
            DataFeed feed = analyticsService.Query(query);

            var returnDictionary = new Dictionary<string, int>();
            foreach (var entry in feed.Entries)
                returnDictionary.Add(((DataEntry)entry).Dimensions[0].Value, Int32.Parse(((DataEntry)entry).Metrics[0].Value));

            return returnDictionary;
        }
    }
}

そして、これは私がそれをまとめるために使用するインターフェースと実装です。

namespace Utilities
{
    public interface IPageViewCounter
    {
        int GetPageViewCount(string relativeUrl, DateTime startDate, DateTime endDate, bool isPathAbsolute = true);
        Dictionary<string, int> PageViewCounts(string pagePathRegEx, DateTime startDate, DateTime endDate);
    }

    public class GooglePageViewCounter : IPageViewCounter
    {
        private string GoogleUserName
        {
            get
            {
                return ConfigurationManager.AppSettings["googleUserName"];
            }
        }

        private string GooglePassword
        {
            get
            {
                return ConfigurationManager.AppSettings["googlePassword"];
            }
        }

        private string GoogleAnalyticsTableName
        {
            get
            {
                return ConfigurationManager.AppSettings["googleAnalyticsTableName"];
            }
        }

        private Analytics analytics;

        public GooglePageViewCounter()
        {
            analytics = new Analytics(GoogleUserName, GooglePassword, GoogleAnalyticsTableName);
        }

        #region IPageViewCounter Members

        public int GetPageViewCount(string relativeUrl, DateTime startDate, DateTime endDate, bool isPathAbsolute = true)
        {
            int output = 0;
            try
            {
                output = analytics.GetPageViewsForPagePath(relativeUrl, startDate, endDate, isPathAbsolute);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }

            return output;
        }

        public Dictionary<string, int> PageViewCounts(string pagePathRegEx, DateTime startDate, DateTime endDate)
        {
            var input = analytics.PageViewCounts(pagePathRegEx, startDate, endDate);
            var output = new Dictionary<string, int>();

            foreach (var item in input)
            {
                if (item.Key.Contains('&'))
                {
                    string[] key = item.Key.Split(new char[] { '?', '&' });
                    string newKey = key[0] + "?" + key.FirstOrDefault(k => k.StartsWith("p="));

                    if (output.ContainsKey(newKey))
                        output[newKey] += item.Value;
                    else
                        output[newKey] = item.Value;
                }
                else
                    output.Add(item.Key, item.Value);
            }
            return output;
        }

        #endregion
    }
}

そして今、残りは明白なものです - web.config 値をアプリケーション構成または webconfig に追加し、IPageViewCounter.GetPageViewCount を呼び出す必要があります。

于 2012-04-24T23:17:28.657 に答える
11

この回答は、独自の Analytics アカウントへのアクセスを希望し、新しいAnalytics Reporting API v4を使用したい方を対象としています。

最近、C# を使用して Google アナリティクス データを取得する方法についてのブログ記事を書きました。すべての詳細については、そこをお読みください。

最初に、OAuth2 で接続するか、サービス アカウントで接続するかを選択する必要があります。あなたが Analytics アカウントを所有していると仮定するので、Google API資格情報ページから「サービス アカウント キー」を作成する必要があります。

それを作成したら、JSON ファイルをダウンロードしてプロジェクトに配置します (私は自分のApp_Dataフォルダーに入れました)。

次に、Google.Apis.AnalyticsReporting.v4 Nuget パッケージをインストールします。Newtonsoft のJson.NETもインストールします。

このクラスをプロジェクトのどこかに含めます。

public class PersonalServiceAccountCred
{
    public string type { get; set; }
    public string project_id { get; set; }
    public string private_key_id { get; set; }
    public string private_key { get; set; }
    public string client_email { get; set; }
    public string client_id { get; set; }
    public string auth_uri { get; set; }
    public string token_uri { get; set; }
    public string auth_provider_x509_cert_url { get; set; }
    public string client_x509_cert_url { get; set; }
}

そして、これがあなたが待ち望んでいたものです: 完全な例です!

string keyFilePath = Server.MapPath("~/App_Data/Your-API-Key-Filename.json");
string json = System.IO.File.ReadAllText(keyFilePath);

var cr = JsonConvert.DeserializeObject(json);

var xCred = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(cr.client_email)
{
    Scopes = new[] {
        AnalyticsReportingService.Scope.Analytics
    }
}.FromPrivateKey(cr.private_key));

using (var svc = new AnalyticsReportingService(
    new BaseClientService.Initializer
    {
        HttpClientInitializer = xCred,
        ApplicationName = "[Your Application Name]"
    })
)
{
    // Create the DateRange object.
    DateRange dateRange = new DateRange() { StartDate = "2017-05-01", EndDate = "2017-05-31" };

    // Create the Metrics object.
    Metric sessions = new Metric { Expression = "ga:sessions", Alias = "Sessions" };

    //Create the Dimensions object.
    Dimension browser = new Dimension { Name = "ga:browser" };

    // Create the ReportRequest object.
    ReportRequest reportRequest = new ReportRequest
    {
        ViewId = "[A ViewId in your account]",
        DateRanges = new List() { dateRange },
        Dimensions = new List() { browser },
        Metrics = new List() { sessions }
    };

    List requests = new List();
    requests.Add(reportRequest);

    // Create the GetReportsRequest object.
    GetReportsRequest getReport = new GetReportsRequest() { ReportRequests = requests };

    // Call the batchGet method.
    GetReportsResponse response = svc.Reports.BatchGet(getReport).Execute();
}

まず、JSON ファイルからサービス アカウント キー情報を逆シリアル化し、それをPersonalServiceAccountCredオブジェクトに変換します。次に、 を作成し、ServiceAccountCredential経由で Google に接続しますAnalyticsReportingService。そのサービスを使用して、いくつかの基本的なフィルターを準備して API に渡し、リクエストを送信します。

変数が宣言されている行にブレークポイントを設定し、responseF10 キーを 1 回押して変数にカーソルを合わせると、応答で使用できるデータを確認できるようになります。

于 2017-06-17T02:29:14.603 に答える
10

v3 Beta の回答にコメントを追加することだけを望んでいましたが、担当者ポイントがそれを妨げています。ただし、他の人がこの情報を持っているといいと思ったので、ここに示します。

using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Services;

これらの名前空間は、その投稿のコード全体で使用されています。私はいつも、人々が名前空間をもっと頻繁に投稿してくれることを願っています. 私はそれらを探すのにかなりの時間を費やしているようです. これにより、何人かの人々が数分の作業を節約できることを願っています。

于 2014-01-16T18:28:03.687 に答える
2

グーグルがいつか適切なドキュメントを提供することを願っています。ここでは、Google アナリティクスのサーバー側認証を ASP.NET C# に統合するためのすべての手順をリストしています。

ステップ 1: Google コンソールでプロジェクトを作成する

リンクhttps://console.developers.google.com/iam-admin/projectsに移動し、[プロジェクトの作成] ボタンをクリックしてプロジェクトを作成し、ポップアップ ウィンドウにプロジェクト名を指定して送信します。

ステップ 2: 認証情報とサービス アカウントを作成する

プロジェクトの作成後、「API Manager」ページにリダイレクトされます。資格情報をクリックし、[資格情報の作成] ボタンを押します。ドロップダウンから「サービス アカウント キー」を選択すると、次のページにリダイレクトされます。サービス アカウントのプルダウンで、[新しいサービス アカウント] を選択します。サービス アカウント名を入力し、p12 キーをダウンロードします。p12 拡張子が付きます。デフォルトのパスワード「notasecret」を含むポップアップが表示され、秘密鍵がダウンロードされます。

ステップ 3: 0auth クライアント ID を作成する

「資格情報の作成」ドロップダウンをクリックし、「0auth クライアント ID」を選択すると、「0auth 同意画面」タブにリダイレクトされます。プロジェクト名のテキスト ボックスにランダムな名前を入力します。アプリケーションの種類として「Web アプリケーション」を選択し、作成ボタンをクリックします。生成されたクライアント ID をメモ帳にコピーします。

ステップ 4: API を有効にする

左側の [概要] タブをクリックし、水平タブから [有効な API] を選択します。検索バーで「Analytics API」を検索し、ドロップダウンをクリックして「有効にする」ボタンを押します。もう一度「Analytics Reporting V4」を検索して有効にします。

ステップ 5: nuget パッケージをインストールする

Visual Studio で、[ツール] > [Nuget パッケージ マネージャー] > [パッケージ マネージャー コンソール] に移動します。以下のコードをコピーしてコンソールに貼り付け、nuget パッケージをインストールします。

インストール パッケージ Google.Apis.Analytics.v3

インストール パッケージ DotNetOpenAuth.Core -バージョン 4.3.4.13329

上記の 2 つのパッケージは、Google アナリティクスと DotNetOpenAuth nuget パッケージです。

ステップ 6: サービス アカウントに「表示と分析」権限を付与する

Google アナリティクス アカウントに移動し、[管理者] タブをクリックして左側のメニューから [ユーザー管理] を選択し、アナリティクス データにアクセスするドメインを選択し、その下にサービス アカウントのメール ID を挿入して、[読み取りと分析] 権限を選択します。ドロップダウンから。サービス アカウントのメール ID は、例: googleanalytics@googleanalytics.iam.gserviceaccount.comのようになります。

作業コード

フロントエンドコード:

以下の分析埋め込みスクリプトをコピーしてフロント エンドに貼り付けるか、Google 分析のドキュメント ページからこのコードを取得することもできます。

 <script>
    (function (w, d, s, g, js, fs) {
        g = w.gapi || (w.gapi = {}); g.analytics = { q: [], ready: function (f) { this.q.push(f); } };
        js = d.createElement(s); fs = d.getElementsByTagName(s)[0];
        js.src = 'https://apis.google.com/js/platform.js';
        fs.parentNode.insertBefore(js, fs); js.onload = function () { g.load('analytics'); };
    }(window, document, 'script'));</script>

以下のコードをフロント エンド ページの body タグに貼り付けます。

 <asp:HiddenField ID="accessToken" runat="server" />
<div id="chart-1-container" style="width:600px;border:1px solid #ccc;"></div>
        <script>
           var access_token = document.getElementById('<%= accessToken.ClientID%>').value;

            gapi.analytics.ready(function () {
                /**
                 * Authorize the user with an access token obtained server side.
                 */
                gapi.analytics.auth.authorize({
                    'serverAuth': {
                        'access_token': access_token
                    }
                });
                /**
                 * Creates a new DataChart instance showing sessions.
                 * It will be rendered inside an element with the id "chart-1-container".
                 */
                var dataChart1 = new gapi.analytics.googleCharts.DataChart({
                    query: {
                        'ids': 'ga:53861036', // VIEW ID <-- Goto your google analytics account and select the domain whose analytics data you want to display on your webpage. From the URL  ex: a507598w53044903p53861036. Copy the digits after "p". It is your view ID
                        'start-date': '2016-04-01',
                        'end-date': '2016-04-30',
                        'metrics': 'ga:sessions',
                        'dimensions': 'ga:date'
                    },
                    chart: {
                        'container': 'chart-1-container',
                        'type': 'LINE',
                        'options': {
                            'width': '100%'
                        }
                    }
                });
                dataChart1.execute();


                /**
                 * Creates a new DataChart instance showing top 5 most popular demos/tools
                 * amongst returning users only.
                 * It will be rendered inside an element with the id "chart-3-container".
                 */


            });
</script>

https://ga-dev-tools.appspot.com/account-explorer/からビュー ID を取得することもできます。

バックエンドコード:

 using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Web.Script.Serialization;
    using System.Net;
    using System.Text;
    using Google.Apis.Analytics.v3;
    using Google.Apis.Analytics.v3.Data;
    using Google.Apis.Services;
    using System.Security.Cryptography.X509Certificates;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Util;
    using DotNetOpenAuth.OAuth2;
    using System.Security.Cryptography;

    namespace googleAnalytics
    {
        public partial class api : System.Web.UI.Page
        {
            public const string SCOPE_ANALYTICS_READONLY = "https://www.googleapis.com/auth/analytics.readonly";

            string ServiceAccountUser = "googleanalytics@googleanalytics.iam.gserviceaccount.com"; //service account email ID
            string keyFile = @"D:\key.p12"; //file link to downloaded key with p12 extension
            protected void Page_Load(object sender, EventArgs e)
            {

               string Token = Convert.ToString(GetAccessToken(ServiceAccountUser, keyFile, SCOPE_ANALYTICS_READONLY));

               accessToken.Value = Token;

                var certificate = new X509Certificate2(keyFile, "notasecret", X509KeyStorageFlags.Exportable);

                var credentials = new ServiceAccountCredential(

                    new ServiceAccountCredential.Initializer(ServiceAccountUser)
                    {
                        Scopes = new[] { AnalyticsService.Scope.AnalyticsReadonly }
                    }.FromCertificate(certificate));

                var service = new AnalyticsService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credentials,
                    ApplicationName = "Google Analytics API"
                });

                string profileId = "ga:53861036";
                string startDate = "2016-04-01";
                string endDate = "2016-04-30";
                string metrics = "ga:sessions,ga:users,ga:pageviews,ga:bounceRate,ga:visits";

                DataResource.GaResource.GetRequest request = service.Data.Ga.Get(profileId, startDate, endDate, metrics);


                GaData data = request.Execute();
                List<string> ColumnName = new List<string>();
                foreach (var h in data.ColumnHeaders)
                {
                    ColumnName.Add(h.Name);
                }


                List<double> values = new List<double>();
                foreach (var row in data.Rows)
                {
                    foreach (var item in row)
                    {
                        values.Add(Convert.ToDouble(item));
                    }

                }
                values[3] = Math.Truncate(100 * values[3]) / 100;

                txtSession.Text = values[0].ToString();
                txtUsers.Text = values[1].ToString();
                txtPageViews.Text = values[2].ToString();
                txtBounceRate.Text = values[3].ToString();
                txtVisits.Text = values[4].ToString();

            }


         public static dynamic GetAccessToken(string clientIdEMail, string keyFilePath, string scope)
        {
            // certificate
            var certificate = new X509Certificate2(keyFilePath, "notasecret");

            // header
            var header = new { typ = "JWT", alg = "RS256" };

            // claimset
            var times = GetExpiryAndIssueDate();
            var claimset = new
            {
                iss = clientIdEMail,
                scope = scope,
                aud = "https://accounts.google.com/o/oauth2/token",
                iat = times[0],
                exp = times[1],
            };

            JavaScriptSerializer ser = new JavaScriptSerializer();

            // encoded header
            var headerSerialized = ser.Serialize(header);
            var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
            var headerEncoded = Convert.ToBase64String(headerBytes);

            // encoded claimset
            var claimsetSerialized = ser.Serialize(claimset);
            var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
            var claimsetEncoded = Convert.ToBase64String(claimsetBytes);

            // input
            var input = headerEncoded + "." + claimsetEncoded;
            var inputBytes = Encoding.UTF8.GetBytes(input);

            // signature
            var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
            var cspParam = new CspParameters
            {
                KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
                KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
            };
            var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
            var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
            var signatureEncoded = Convert.ToBase64String(signatureBytes);

            // jwt
            var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;

            var client = new WebClient();
            client.Encoding = Encoding.UTF8;
            var uri = "https://accounts.google.com/o/oauth2/token";
            var content = new NameValueCollection();

            content["assertion"] = jwt;
            content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";

            string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));


            var result = ser.Deserialize<dynamic>(response);

            object pulledObject = null;

            string token = "access_token";
            if (result.ContainsKey(token))
            {
                pulledObject = result[token];
            }


            //return result;
            return pulledObject;
        }

        private static int[] GetExpiryAndIssueDate()
        {
            var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            var issueTime = DateTime.UtcNow;

            var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
            var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds;

            return new[] { iat, exp };
        }

        }
    }
于 2016-05-31T06:31:41.673 に答える
0

別の作業アプローチ

以下のコードを ConfigAuth に追加します。

  var googleApiOptions = new GoogleOAuth2AuthenticationOptions()
        {
            AccessType = "offline", // can use only if require
            ClientId = ClientId,
            ClientSecret = ClientSecret,
            Provider = new GoogleOAuth2AuthenticationProvider()
            {
                OnAuthenticated = context =>
                {
                    context.Identity.AddClaim(new Claim("Google_AccessToken", context.AccessToken));

                    if (context.RefreshToken != null)
                    {
                        context.Identity.AddClaim(new Claim("GoogleRefreshToken", context.RefreshToken));
                    }
                    context.Identity.AddClaim(new Claim("GoogleUserId", context.Id));
                    context.Identity.AddClaim(new Claim("GoogleTokenIssuedAt", DateTime.Now.ToBinary().ToString()));
                    var expiresInSec = 10000;
                    context.Identity.AddClaim(new Claim("GoogleTokenExpiresIn", expiresInSec.ToString()));


                    return Task.FromResult(0);
                }
            },

            SignInAsAuthenticationType = DefaultAuthenticationTypes.ApplicationCookie
        };
        googleApiOptions.Scope.Add("openid"); // Need to add for google+ 
        googleApiOptions.Scope.Add("profile");// Need to add for google+ 
        googleApiOptions.Scope.Add("email");// Need to add for google+ 
        googleApiOptions.Scope.Add("https://www.googleapis.com/auth/analytics.readonly");

        app.UseGoogleAuthentication(googleApiOptions);

以下のコード、名前空間、および相対参照を追加します

 using Google.Apis.Analytics.v3;
 using Google.Apis.Analytics.v3.Data;
 using Google.Apis.Auth.OAuth2;
 using Google.Apis.Auth.OAuth2.Flows;
 using Google.Apis.Auth.OAuth2.Responses;
 using Google.Apis.Services;
 using Microsoft.AspNet.Identity;
 using Microsoft.Owin.Security;
 using System;
 using System.Threading.Tasks;
 using System.Web;
 using System.Web.Mvc;

public class HomeController : Controller
{
    AnalyticsService service;
    public IAuthenticationManager AuthenticationManager
    {
        get
        {
            return HttpContext.GetOwinContext().Authentication;
        }
    }

    public async Task<ActionResult> AccountList()
    {
        service = new AnalyticsService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = await GetCredentialForApiAsync(),
            ApplicationName = "Analytics API sample",
        });


        //Account List
        ManagementResource.AccountsResource.ListRequest AccountListRequest = service.Management.Accounts.List();
        //service.QuotaUser = "MyApplicationProductKey";
        Accounts AccountList = AccountListRequest.Execute();



        return View();
    }

    private async Task<UserCredential> GetCredentialForApiAsync()
    {
        var initializer = new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = new ClientSecrets
            {
                ClientId = ClientId,
                ClientSecret = ClientSecret,
            },
            Scopes = new[] { "https://www.googleapis.com/auth/analytics.readonly" }
        };
        var flow = new GoogleAuthorizationCodeFlow(initializer);

        var identity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ApplicationCookie);
        if (identity == null)
        {
            Redirect("/Account/Login");
        }

        var userId = identity.FindFirstValue("GoogleUserId");

        var token = new TokenResponse()
        {
            AccessToken = identity.FindFirstValue("Google_AccessToken"),
            RefreshToken = identity.FindFirstValue("GoogleRefreshToken"),
            Issued = DateTime.FromBinary(long.Parse(identity.FindFirstValue("GoogleTokenIssuedAt"))),
            ExpiresInSeconds = long.Parse(identity.FindFirstValue("GoogleTokenExpiresIn")),
        };

        return new UserCredential(flow, userId, token);
    }
}

これを Global.asax の Application_Start() に追加します。

  AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
于 2015-12-25T13:16:32.260 に答える