关于 .net:使用 Google Analytics API 在 C# 中显示信息

Use Google Analytics API to show information in C#

我整天都在寻找一个好的解决方案,但 google 发展如此之快,以至于我无法找到有效的解决方案。我想要做的是,我有一个 Web 应用程序,它有一个管理部分,用户需要登录才能查看信息。在本节中,我想展示一些来自 GA 的数据,例如某些特定 url 的综合浏览量。因为它不是我显示的用户信息,而是谷歌分析用户,我想连接传递信息(用户名/密码或 APIKey),但我不知道如何。我发现的所有示例都使用 OAuth2(如果我理解,女巫会要求访问者使用 google 登录)。

到目前为止我发现了什么:

  • .Net 的 Google 官方客户端库:http://code.google.com/p/google-api-dotnet-client/,没有 GA 示例
  • 官方开发者帮助:https://developers.google.com/analytics/
  • 另一个关于 SO 代码的问题:Google Analytics API - Programmatically fetch page views in server side but I get a 403 when I try to authentication
  • 一些访问 API 的源:http://www.reimers.dk/jacob-reimers-blog/added-google-analytics-reader-for-net 下载了源,但我不知道它是如何工作的
  • 关于 SO 的另一个问题:Google Analytics Access with C# 但它没有帮助
  • 在写这篇文章时,他们向我推荐了这篇 09 年的旧帖子 Google Analytics API 和 .Net...

也许我只是累了,明天很容易找到解决办法,但现在我需要帮助!

谢谢


它需要在 google 端进行一些设置,但实际上非常简单。我会一步一步列出来。

首先,您需要在 Google 云控制台中创建一个应用程序并启用 Analytics API。

  • 转到 http://code.google.com/apis/console
  • 如果您还没有项目,请选择下拉菜单并创建一个项目
  • 创建项目后,单击服务
  • 从这里启用分析 API

现在已启用 Analytics API,下一步将是启用服务帐户以访问您所需的分析配置文件/站点。服务帐户将允许您登录,而无需提示用户输入凭据。

  • 转到 http://code.google.com/apis/console 并选择您的项目
    从下拉列表中创建。
  • 接下来转到"API 访问"部分并单击"创建另一个客户端 ID"按钮。
  • 在 Create Client ID 窗口中选择服务帐户并单击
    创建客户 ID。
  • 如果此帐户未启动,请下载此帐户的公钥
    自动下载。您稍后在编写代码时将需要它
    授权。
  • 在退出之前复制服务帐户自动生成的电子邮件地址,因为您将在下一步中需要它。客户电子邮件看起来像 @developer.gserviceaccount.com

现在我们有一个服务帐户,您需要允许该服务帐户访问您在 Google Analytics(分析)中的个人资料/网站。

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

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

从 NuGet 获取这个包:

Google.Apis.Analytics.v3 客户端库

添加这些用法:

1
2
3
4
5
6
7
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 )。
  • 应用程序名称是您选择的名称,它告诉 google api 正在访问它的内容(又名:它可以是您选择的任何内容)。

那么做一些基本调用的代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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; }
    }
}

其他有用的链接:

Analytic API Explorer - 从 Web 查询 API

Analytic API Explorer 版本 2 - 从 Web 查询 API

维度和指标参考

希望这对将来尝试这样做的人有所帮助。


我做了很多搜索,最后要么从多个地方查找代码,然后围绕它package我自己的界面,我想出了以下解决方案。不确定人们是否将整个代码粘贴在这里,但我想为什么不节省其他人的时间:)

先决条件,您需要安装 Google.GData.Client 和 google.gdata.analytics 包/dll。

这是完成这项工作的主要类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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;
        }
    }
}

这是我用来package它的接口和实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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


此答案适用于希望访问自己的 Google Analytics(分析)帐户并希望使用新的 Analytics Reporting API v4 的人。

我最近写了一篇关于如何使用 C# 获取 Google Analytics 数据的博客文章。阅读那里了解所有详细信息。

您首先需要在连接 OAuth2 或服务帐户之间进行选择。我假设您拥有 Analytics 帐户,因此您需要从 Google API 凭据页面创建一个"服务帐户密钥"。

创建后,下载 JSON 文件并将其放入您的项目中(我将我的放在我的 App_Data 文件夹中)。

接下来,安装 Google.Apis.AnalyticsReporting.v4 Nuget 包。同时安装 Newtonsoft 的 Json.NET。

在你的项目中包含这个类:

1
2
3
4
5
6
7
8
9
10
11
12
13
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; }
}

这就是你一直在等待的:一个完整??的例子!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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,然后将鼠标悬停在变量上,这样您就可以看到哪些数据可供您在响应中使用.


我希望只是为 v3 Beta 的答案添加评论,但代表点阻止了这一点。但是,我认为其他人有这些信息会很好,所以这里是:

1
2
3
4
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Services;

这些名称空间在该帖子的整个代码中使用。我一直希望人们能更频繁地发布名称空间,我似乎花了很多时间寻找它们。我希望这可以为一些人节省几分钟的工作时间。


我在 nuGet 包中设置了与上述答案非常相似的东西。它执行以下操作:
- 连接到您在 API 控制台中设置的"服务帐户"
- 提取您想要的任何 Google Analytics(分析)数据
- 使用 Google 的 Charts API 显示该数据
它以一种非常容易修改的方式完成所有这些工作。您可以在此处查看更多信息:https://www.nuget.org/packages/GoogleAnalytics.GoogleCharts.NET/。


希望谷歌有一天会提供适当的文档。在这里,我列出了在 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

以上两个包是谷歌分析和DotNetOpenAuth nuget包。

第 6 步:向服务帐户

提供"查看和分析"权限

转到谷歌分析帐户并单击"管理"选项卡并从左侧菜单中选择"用户管理",选择您要访问分析数据的域并在其下插入服务帐户电子邮件 ID,然后从下拉列表中选择"读取和分析"权限。服务帐户电子邮件 ID 类似于 ex:[email protected]

工作代码

前端代码:

将以下分析嵌入脚本复制并粘贴到您的前端,否则您也可以从谷歌分析文档页面获取此代码。

1
2
3
4
5
6
    (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'));

将以下代码粘贴到前端页面的正文标记中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
           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".
                 */



            });

您还可以从 https://ga-dev-tools.appspot.com/account-explorer/

获取您的视图 ID

后端代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
 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 ="[email protected]"; //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 };
        }

        }
    }


另一种工作方法

在 ConfigAuth 中添加以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  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);

在下面添加代码、名称空间和相关引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 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() 中添加这个

1
  AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;