正确验证以访问 Google 通讯录... (C#/MVC3)

发布于 2024-11-03 02:42:05 字数 3225 浏览 3 评论 0原文

我现在有一个非常简单的 MVC 应用程序:
控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome!";

        var qs = HttpContext.Request.QueryString;
        var keys = qs.AllKeys.ToList();
        if (keys.Count > 0 && keys.Contains("token"))
        {
            Session["token"] = qs.Get("token");
            Models.GoogleContact gc = new Models.GoogleContact();
        }
        else
        {
            ViewBag.GoogleUrl = AuthSubUtil.getRequestUrl(HttpContext.Request.Url.AbsoluteUri, "https://www.google.com/m8/feeds/", false, true);
        }

        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

我有这个主页视图

@{
    ViewBag.Title = "Home Page";
}

<p>Home Page...</p>

<a href="@ViewBag.GoogleUrl">Tie in with Google</a>
<br />
<br />

当应用程序首次启动时,没有查询字符串,因此控制器将创建我嵌入主页的链接。你点击这个链接,它就会把你带到谷歌。授权您希望此应用程序能够访问 Google 通讯录,然后它会带着查询字符串返回主页。控制器看到查询字符串,剥离令牌并实例化 Google“模型”类。

基类:

internal class baseGoogle
{
    #region Private Properties
    internal const string googleContactToken = "cp";
    internal const string googleCalendarToken = "cl";
    internal string _authSubToken;
    internal GAuthSubRequestFactory _gAuthSubRequestFactory;
    internal RequestSettings _requestSettings;
    internal ContactsRequest _contactsRequest;
    internal ContactsService _contactsService;
    #endregion

    internal baseGoogle()
    {
#if DEBUG
        _authSubToken = HttpContext.Current.Session["token"].ToString();
        _gAuthSubRequestFactory = new Google.GData.Client.GAuthSubRequestFactory(googleContactToken, "Tester1");
        _requestSettings = new Google.GData.Client.RequestSettings(_gAuthSubRequestFactory.ApplicationName, _authSubToken);
        _contactsRequest = new Google.Contacts.ContactsRequest(_requestSettings);
        _contactsService = new Google.GData.Contacts.ContactsService(_gAuthSubRequestFactory.ApplicationName);
        _contactsService.RequestFactory = _gAuthSubRequestFactory;
#endif
    }
}

我的 Google 联系人类:

internal class GoogleContact : baseGoogle
{
    #region Public Properties
    [NotMapped]
    public Dictionary<string, Group> Groups { get; set; }
    #endregion

    public GoogleContact() : base()
    {
        // Get the list of contact groups...
        _requestSettings.AutoPaging = true;
        Feed<Group> fg = _contactsRequest.GetGroups();

        foreach (Group g in fg.Entries)
        {
            this.Groups.Add(g.Title, g);
        }

    }
}

在我尝试迭代 Feed 项目之前,一切似乎都工作正常。此时它会弹出401 - Unauthorized错误。

对于为什么这样做有什么想法吗?我正在关注 Google Dev 上的文档。

我正在使用 1.7.0.1 版本的 API。


注意:我找到了一个博客输入 一些不同的代码,你猜怎么着,这有效。现在来弄清楚为什么半官方方式行不通!有人有什么想法吗?

I have a very simple MVC app at this point:
Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome!";

        var qs = HttpContext.Request.QueryString;
        var keys = qs.AllKeys.ToList();
        if (keys.Count > 0 && keys.Contains("token"))
        {
            Session["token"] = qs.Get("token");
            Models.GoogleContact gc = new Models.GoogleContact();
        }
        else
        {
            ViewBag.GoogleUrl = AuthSubUtil.getRequestUrl(HttpContext.Request.Url.AbsoluteUri, "https://www.google.com/m8/feeds/", false, true);
        }

        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

I have this Home View:

@{
    ViewBag.Title = "Home Page";
}

<p>Home Page...</p>

<a href="@ViewBag.GoogleUrl">Tie in with Google</a>
<br />
<br />

When the app first launches there is no query string so the Controller will create the link that I embed on the Home page. You click the link and it shoots you off to Google. Authorize that you wish for this app to have access to the Google Contacts and it returns with a query string back to the home page. The Controller sees the query string, strips off the token and instantiates a Google "Model" class.

Base Class:

internal class baseGoogle
{
    #region Private Properties
    internal const string googleContactToken = "cp";
    internal const string googleCalendarToken = "cl";
    internal string _authSubToken;
    internal GAuthSubRequestFactory _gAuthSubRequestFactory;
    internal RequestSettings _requestSettings;
    internal ContactsRequest _contactsRequest;
    internal ContactsService _contactsService;
    #endregion

    internal baseGoogle()
    {
#if DEBUG
        _authSubToken = HttpContext.Current.Session["token"].ToString();
        _gAuthSubRequestFactory = new Google.GData.Client.GAuthSubRequestFactory(googleContactToken, "Tester1");
        _requestSettings = new Google.GData.Client.RequestSettings(_gAuthSubRequestFactory.ApplicationName, _authSubToken);
        _contactsRequest = new Google.Contacts.ContactsRequest(_requestSettings);
        _contactsService = new Google.GData.Contacts.ContactsService(_gAuthSubRequestFactory.ApplicationName);
        _contactsService.RequestFactory = _gAuthSubRequestFactory;
#endif
    }
}

My Google Contacts Class:

internal class GoogleContact : baseGoogle
{
    #region Public Properties
    [NotMapped]
    public Dictionary<string, Group> Groups { get; set; }
    #endregion

    public GoogleContact() : base()
    {
        // Get the list of contact groups...
        _requestSettings.AutoPaging = true;
        Feed<Group> fg = _contactsRequest.GetGroups();

        foreach (Group g in fg.Entries)
        {
            this.Groups.Add(g.Title, g);
        }

    }
}

Everything appears to be working fine until I try to iterate the Feed items. It pops a 401 - Unauthorized error at that point.

Any ideas of why it is doing this? I am following the docs up on Google Dev.

I am using the 1.7.0.1 version of the APIs.


NOTE: I found a blog entry with some different code and guess what, that works. Now to figure out why the semi-official way does not work! Anyone with any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽心 2024-11-10 02:42:05

经过大量尝试后,我发现了一种完成我需要的方法。首先,我无法找到一种使用 OpenID 授权令牌来获取用户联系人、日历等的方法。我仍在寻找一种方法来做到这一点。 (在这里查看我的问题

我发现的是让一个人在他的个人资料中输入他的谷歌用户名和密码,然后使用它通过 GData 连接到他们的信息。我的感觉是大多数人都不想这样做! (而且这是相当多余的!)

这是我想出的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using Google.GData.Contacts;
using Google.GData.Extensions;

namespace myNameSpace
{
    /// 
    /// Summary description for GoogleContactService
    /// 
    public class GoogleContactService
    {
        #region Properties
        public static ContactsService GContactService = null;
        #endregion

        #region Methods
        public static void InitializeService(string username, string password)
        {
            GContactService = new ContactsService("Contact Infomation");
            GContactService.setUserCredentials(username, password);
        }
        public static List<ContactDetail> GetContacts(string GroupName = null)
        {
            List<ContactDetail> contactDetails = new List<ContactDetail>();
            ContactsQuery contactQuery = new ContactsQuery(ContactsQuery.CreateContactsUri("default"));
            contactQuery.NumberToRetrieve = 1000;

            if (!String.IsNullOrEmpty(GroupName))
            {
                GroupEntry ge = GetGroup(GroupName);
                if (ge != null)
                    contactQuery.Group = ge.Id.AbsoluteUri;
            }
            else
            {
                string groupName = "";
                GroupEntry ge = GetGroup(groupName);
                if (ge != null)
                    contactQuery.Group = ge.Id.AbsoluteUri;
            }

            ContactsFeed feed = GContactService.Query(contactQuery);
            foreach (ContactEntry entry in feed.Entries)
            {
                ContactDetail contact = new ContactDetail
                {
                    Name = entry.Title.Text,
                    EmailAddress1 = entry.Emails.Count >= 1 ? entry.Emails[0].Address : "",
                    EmailAddress2 = entry.Emails.Count >= 2 ? entry.Emails[1].Address : "",
                    Phone1 = entry.Phonenumbers.Count >= 1 ? entry.Phonenumbers[0].Value : "",
                    Phone2 = entry.Phonenumbers.Count >= 2 ? entry.Phonenumbers[1].Value : "",
                    Address = entry.PostalAddresses.Count >= 1 ? entry.PostalAddresses[0].FormattedAddress : "",
                    Details = entry.Content.Content
                };

                contact.UserDefinedFields = new List<UDT>();
                foreach ( var udt in entry.UserDefinedFields)
                {
                    contact.UserDefinedFields.Add(new UDT { Key = udt.Key, Value = udt.Value });
                }

                contactDetails.Add(contact);
            }

            return contactDetails;
        }
        #endregion

        #region Helpers
        private static GroupEntry GetGroup(string GroupName)
        {
            GroupEntry groupEntry = null;

            GroupsQuery groupQuery = new GroupsQuery(GroupsQuery.CreateGroupsUri("default"));
            groupQuery.NumberToRetrieve = 100;
            GroupsFeed groupFeed = GContactService.Query(groupQuery);
            foreach (GroupEntry entry in groupFeed.Entries)
            {
                if (entry.Title.Text.Equals(GroupName, StringComparison.CurrentCultureIgnoreCase))
                {
                    groupEntry = entry;
                    break;
                }
            }
            return groupEntry;
        }
        #endregion
    }

    public class ContactDetail
    {
        public string Name { get; set; }
        public string EmailAddress1 { get; set; }
        public string EmailAddress2 { get; set; }
        public string Phone1 { get; set; }
        public string Phone2 { get; set; }
        public string Address { get; set; }
        public string Details { get; set; }
        public string Pipe { get; set; }
        public string Relationship { get; set; }
        public string Status { get; set; }
        public List<UDT> UserDefinedFields { get; set; }
    }
    public class UDT
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }
}

现在,弄清楚如何使用他们的 OpenID 登录,而不必询问他们的登录凭据!

After a lot of playing around I discovered one way to accomplish what I needed. First off, I could not discover a way to use the OpenID authorization token to get at that users contacts, calendar, etc. I am still looking for a way to do that. (see my question here)

What I did figure out was to have a person enter his google username and password in his profile then use that to connect via GData to their info. My feeling is most people would NOT want to do this! (And it is rather redundant!)

Here is the code I came up with:

using System;
using System.Collections.Generic;
using System.Linq;
using Google.GData.Contacts;
using Google.GData.Extensions;

namespace myNameSpace
{
    /// 
    /// Summary description for GoogleContactService
    /// 
    public class GoogleContactService
    {
        #region Properties
        public static ContactsService GContactService = null;
        #endregion

        #region Methods
        public static void InitializeService(string username, string password)
        {
            GContactService = new ContactsService("Contact Infomation");
            GContactService.setUserCredentials(username, password);
        }
        public static List<ContactDetail> GetContacts(string GroupName = null)
        {
            List<ContactDetail> contactDetails = new List<ContactDetail>();
            ContactsQuery contactQuery = new ContactsQuery(ContactsQuery.CreateContactsUri("default"));
            contactQuery.NumberToRetrieve = 1000;

            if (!String.IsNullOrEmpty(GroupName))
            {
                GroupEntry ge = GetGroup(GroupName);
                if (ge != null)
                    contactQuery.Group = ge.Id.AbsoluteUri;
            }
            else
            {
                string groupName = "";
                GroupEntry ge = GetGroup(groupName);
                if (ge != null)
                    contactQuery.Group = ge.Id.AbsoluteUri;
            }

            ContactsFeed feed = GContactService.Query(contactQuery);
            foreach (ContactEntry entry in feed.Entries)
            {
                ContactDetail contact = new ContactDetail
                {
                    Name = entry.Title.Text,
                    EmailAddress1 = entry.Emails.Count >= 1 ? entry.Emails[0].Address : "",
                    EmailAddress2 = entry.Emails.Count >= 2 ? entry.Emails[1].Address : "",
                    Phone1 = entry.Phonenumbers.Count >= 1 ? entry.Phonenumbers[0].Value : "",
                    Phone2 = entry.Phonenumbers.Count >= 2 ? entry.Phonenumbers[1].Value : "",
                    Address = entry.PostalAddresses.Count >= 1 ? entry.PostalAddresses[0].FormattedAddress : "",
                    Details = entry.Content.Content
                };

                contact.UserDefinedFields = new List<UDT>();
                foreach ( var udt in entry.UserDefinedFields)
                {
                    contact.UserDefinedFields.Add(new UDT { Key = udt.Key, Value = udt.Value });
                }

                contactDetails.Add(contact);
            }

            return contactDetails;
        }
        #endregion

        #region Helpers
        private static GroupEntry GetGroup(string GroupName)
        {
            GroupEntry groupEntry = null;

            GroupsQuery groupQuery = new GroupsQuery(GroupsQuery.CreateGroupsUri("default"));
            groupQuery.NumberToRetrieve = 100;
            GroupsFeed groupFeed = GContactService.Query(groupQuery);
            foreach (GroupEntry entry in groupFeed.Entries)
            {
                if (entry.Title.Text.Equals(GroupName, StringComparison.CurrentCultureIgnoreCase))
                {
                    groupEntry = entry;
                    break;
                }
            }
            return groupEntry;
        }
        #endregion
    }

    public class ContactDetail
    {
        public string Name { get; set; }
        public string EmailAddress1 { get; set; }
        public string EmailAddress2 { get; set; }
        public string Phone1 { get; set; }
        public string Phone2 { get; set; }
        public string Address { get; set; }
        public string Details { get; set; }
        public string Pipe { get; set; }
        public string Relationship { get; set; }
        public string Status { get; set; }
        public List<UDT> UserDefinedFields { get; set; }
    }
    public class UDT
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }
}

Now, to figure out how to use their OpenID login instead of having to ask for their login credentials!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文