使用Google Analytics API在C#中显示信息

51
我一整天都在寻找一个好的解决方案,但是 Google 更新太快了,我找不到有效的方法。我的 Web 应用程序有一个管理部分,用户需要登录才能查看信息。在这个部分中,我想显示来自 GA 的一些数据,例如特定 URL 的页面浏览量。由于我显示的不是用户信息,而是 Google Analytics 用户,所以我想连接并传递信息(用户名/密码或 APIKey),但是我找不到如何做到这一点。我找到的所有示例都使用 OAuth2(如果我理解正确,将要求访问者使用 Google 登录)。目前为止我找到了以下资料:也许我只是累了,明天就会容易找到解决方案,但现在我需要帮助!

谢谢


我能够绕过你在我的Google Analytics Api v3应用程序中遇到的所有问题(我也曾经面临过),从.NET 4.0 C# WCF服务中获取数据。在.NET中使用最新的v3版本确实是一个真正的挑战。 - Kamran Shahid
7个回答

92
需要在谷歌方面进行一些设置,但实际上非常简单。我将逐步列出如下: 首先,您需要在Google云控制台中创建一个应用程序并启用Analytics API。 现在,Analytics API已启用,下一步是启用服务帐户以访问所需的分析配置文件/站点。服务帐户将允许您登录而无需提示用户输入凭据。
  • 进入http://code.google.com/apis/console并从下拉菜单中选择您创建的项目。
  • 接下来进入“API访问”部分,点击“创建另一个客户端ID”按钮。
  • 在“创建客户端ID”窗口中选择服务帐户并单击创建客户端ID。
  • 如果未自动开始下载,请下载此帐户的公共密钥。以后编写授权代码时将需要此密钥。
  • 退出之前,请复制服务帐户自动生成的电子邮件地址,因为您将在下一步中需要它。客户端电子邮件看起来像@developer.gserviceaccount.com

现在我们有了一个服务帐户,您需要允许该服务帐户访问您在Google Analytics中的配置文件/站点。

  • 登录Google Analytics。
  • 登录后,在屏幕左下角单击“管理”按钮。
  • 在管理中,点击账户下拉菜单,选择您希望服务账户能够访问的账户/站点,然后在账户部分下点击“用户管理”。
  • 输入为您的服务账户生成的电子邮件地址,并授予其读取和分析权限。
  • 对于您希望服务可以访问的任何其他账户/站点,请重复这些步骤。

现在已经完成了通过API让服务账户访问Google Analytics的设置,我们可以开始编码了。

从NuGet获取以下包:

Google.Apis.Analytics.v3 Client Library

添加以下using:

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 System.Collections.Generic; 
using System.Linq;

请注意以下事项:
- keyPath是您下载的带有.p12文件扩展名的密钥文件的路径。 - accountEmailAddress是我们之前获取的API电子邮件地址。 - Scope是Google.Apis.Analytics.v3.AnalyticService类中的枚举,指定要使用的URL进行授权(例如:AnalyticsService.Scope.AnalyticsReadonly)。 - Application name是您选择的名称,告诉Google API谁在访问它(也可以选择任何名称)。
然后进行一些基本调用的代码如下。
public class GoogleAnalyticsAPI
{
    public AnalyticsService Service { get; set; }

    public GoogleAnalyticsAPI(string keyPath, string accountEmailAddress)
    {
        var certificate = new X509Certificate2(keyPath, "notasecret", X509KeyStorageFlags.Exportable);

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

        Service = new AnalyticsService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credentials,
                ApplicationName = "WorthlessVariable"
            });
    }

    public AnalyticDataPoint GetAnalyticsData(string profileId, string[] dimensions, string[] metrics, DateTime startDate, DateTime endDate)
    {
        AnalyticDataPoint data = new AnalyticDataPoint();
        if (!profileId.Contains("ga:"))
            profileId = string.Format("ga:{0}", profileId);

        //Make initial call to service.
        //Then check if a next link exists in the response,
        //if so parse and call again using start index param.
        GaData response = null;
        do
        {
            int startIndex = 1;
            if (response != null && !string.IsNullOrEmpty(response.NextLink))
            {
                Uri uri = new Uri(response.NextLink);
                var paramerters = uri.Query.Split('&');
                string s = paramerters.First(i => i.Contains("start-index")).Split('=')[1];
                startIndex = int.Parse(s);
            }

            var request = BuildAnalyticRequest(profileId, dimensions, metrics, startDate, endDate, startIndex);
            response = request.Execute();
            data.ColumnHeaders = response.ColumnHeaders;
            data.Rows.AddRange(response.Rows);

        } while (!string.IsNullOrEmpty(response.NextLink));

        return data;
    }

    private DataResource.GaResource.GetRequest BuildAnalyticRequest(string profileId, string[] dimensions, string[] metrics,
                                                                        DateTime startDate, DateTime endDate, int startIndex)
    {
        DataResource.GaResource.GetRequest request = Service.Data.Ga.Get(profileId, startDate.ToString("yyyy-MM-dd"),
                                                                            endDate.ToString("yyyy-MM-dd"), string.Join(",", metrics));
        request.Dimensions = string.Join(",", dimensions);
        request.StartIndex = startIndex;
        return request;
    }

    public IList<Profile> GetAvailableProfiles()
    {
        var response = Service.Management.Profiles.List("~all", "~all").Execute();
        return response.Items;
    }

    public class AnalyticDataPoint
    {
        public AnalyticDataPoint()
        {
            Rows = new List<IList<string>>();
        }

        public IList<GaData.ColumnHeadersData> ColumnHeaders { get; set; }
        public List<IList<string>> Rows { get; set; }
    }
}

其他有用的链接:

分析API浏览器-从Web查询API

分析API浏览器版本2-从Web查询API

尺寸和指标参考

希望这些对未来尝试做这件事情的人有所帮助。


7
太棒了!在Google .NET API的海洋中游泳一天后,这篇文章就是我的圣杯。你是否使用过Google.Apis.Oauth2.v2?等我获取了电子邮件地址的权限后,我会尝试使用它的。XD - craastad
1
OAuth2Authenticator 实际上来自于 Google APIs OAuth2 客户端库。 - LiquaFoo
2
@craastad,如果你在 Visual Studio 中搜索,这个包叫做 Google APIs OAuth2 客户端库。如果你想从 NuGets 网站下载,可以在这里获取:http://www.nuget.org/packages/Google.Apis.Authentication/1.5.0-beta - LiquaFoo
2
干得好。感谢您浏览文档并呈现出这个结果。 - Elan Hasson
1
@anna 很难确定错误的具体原因,因为它非常模糊,但是谷歌在他们的文档中解决了无效授权错误以及需要检查的内容。请查看此链接底部的“无效授权”部分。https://developers.google.com/analytics/devguides/reporting/core/v2/gdataAuthentication - LiquaFoo
显示剩余19条评论

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


1
谢谢帮助!下载dll:http://code.google.com/p/google-gdata/ 请注意,还有很好的.NET示例! - VinnyG
我需要激活API访问或其他什么吗? - VinnyG
不,我不记得为此做过任何事情,但如果你做了,请提一下。 - MoXplod
好的。你在web.config文件中做了哪些更改,你具体显示了什么数据,总页面浏览量而不是访问量?谢谢。 - WhoAmI
在这个上下文中,'table' 是什么意思? - Lee Englestone

12
这篇文章是为了那些想要访问自己的Analytics账户并使用新的Analytics Reporting API v4的人而写的。
我最近写了一篇博客文章,介绍如何使用C#获取Google Analytics数据。请阅读该文章以获取所有详细信息。
首先,您需要选择OAuth2或服务账户之间的连接方式。假设您拥有Analytics帐户,则需要从Google APIs 凭据页面创建一个“服务账户密钥”。
创建完成后,下载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并通过AnalyticsReportingService连接到Google。使用该服务,我们然后准备一些基本过滤器传递给API并发送请求。
最好在声明response变量的代码行上设置断点,按F10一次,然后悬停在变量上,以便您可以查看响应中可用的数据。

1
抱歉,但这绝对不是一个完整的示例。首先:我应该把第二个代码块放在哪里?我们将使用/显示什么数据? - Nash Carp
第二个代码块可以放在任何你想从Google API检索数据的地方。由于我的项目是一个ASP.NET MVC项目,我把它放在了控制器操作中。你可以把它放在任何你想要的地方。正如我在最后一段中所写的,将断点放在带有“response”变量的行上,当它被命中时,将鼠标悬停在其上以查看它具有哪些属性,并且你可以构建你的代码来提取所需的数据。 - John Washam
我已经按照这个指南进行了操作:http://www.markwemekamp.com/blog/c/how-to-read-from-google-analytics-using-c/ - Nash Carp

10

我本来想在v3 Beta的答案下添加一条评论,但是声望积分不允许。不过,我认为让其他人知道这些信息也是很好的,所以在这里提供:

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

这些命名空间在那篇文章的代码中使用。我总是希望人们更经常地发布命名空间,因为我似乎花了很多时间寻找它们。我希望这可以节省一些人几分钟的工作时间。


3
我已经在nuGet包中设置了与上述答案非常相似的内容。它可以做到以下几点: - 连接到您在API控制台中设置的“服务帐户” - 拉取您想要的任何Google Analytics数据 - 使用Google的Charts API显示这些数据
而且,所有这些都可以非常容易地进行修改。您可以在此处查看更多信息:https://www.nuget.org/packages/GoogleAnalytics.GoogleCharts.NET/

2

希望谷歌有一天能够提供适当的文档。在这里,我列出了将Google Analytics服务器端身份验证集成到ASP.NET C#中的所有步骤。

第1步:在Google控制台中创建项目

访问链接https://console.developers.google.com/iam-admin/projects并通过单击“创建项目”按钮并在弹出窗口中提供项目名称来创建项目。

第2步:创建凭据和服务账号

创建项目后,您将被重定向到“API管理器”页面。单击凭据并按“创建凭据”按钮。从下拉菜单中选择“服务帐户密钥”,您将被重定向到下一页。在服务帐户下拉列表中,选择“新服务帐户”。填写服务帐户名称并下载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包。

Install-Package Google.Apis.Analytics.v3

Install-Package DotNetOpenAuth.Core -Version 4.3.4.13329

以上两个包是Google Analytics和DotNetOpenAuth nuget包。

第6步:向服务帐户提供“查看和分析”权限

进入Google Analytics帐户,单击“管理”选项卡,然后从左侧菜单中选择“用户管理”,选择要访问分析数据的域,并在其中插入服务帐户电子邮件ID,并从下拉菜单中选择“读取和分析”权限。服务帐户电子邮件ID类似于ex:googleanalytics@googleanalytics.iam.gserviceaccount.com

工作代码

前端代码:

将以下Analytics嵌入脚本复制并粘贴到前端,或者您还可以从Google Analytics文档页面获取此代码。

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

        }
    }

1
我认为这个解决方案是次优的,因为您在网页中以明文形式发布了秘密令牌!如果您拥有Google Analytics数据并且是唯一能够访问网页的人,则可以接受,但如果它被共享,我认为这不是一个好主意。 - Phil

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接