简体   繁体   English

如何通过Oauth2身份验证使用Google Contacts API

[英]How to use Google Contacts API via Oauth2 authentication

I have this below code to get calendar entries using the google Calendar API ( https://developers.google.com/google-apps/calendar/ ) which uses OAuth2. 我在下面的代码中使用使用OAuth2的Google Calendar API( https://developers.google.com/google-apps/calendar/ )获取日历条目。 It works well. 它运作良好。

private IList<string> scopes = new List<string>();
private CalendarService calendarService;

private void InitializeCalendarService()
{
        // Add the calendar specific scope to the scopes list
        scopes.Add(CalendarService.Scopes.Calendar.GetStringValue());

        // Display the header and initialize the sample
        CommandLine.EnableExceptionHandling();
        CommandLine.DisplayGoogleSampleHeader("Google.Api.Calendar.v3 Sample");

        // Create the authenticator
        //FullClientCredentials credentials = PromptingClientCredentials.EnsureFullClientCredentials();
        var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);

        FullClientCredentials credentials = new FullClientCredentials();
        credentials.ClientId = "XYZ.apps.googleusercontent.com";
        credentials.ClientSecret = "XYZ";
        credentials.ApiKey = "XYZ";

        provider.ClientIdentifier = credentials.ClientId;
        provider.ClientSecret = credentials.ClientSecret;
        OAuth2Authenticator<NativeApplicationClient> auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);

        // Create the calendar service using an initializer instance
        BaseClientService.Initializer initializer = new BaseClientService.Initializer();
        initializer.Authenticator = auth;
        calendarService = new CalendarService(initializer);

        CalendarList list = calendarService.CalendarList.List().Execute();
        // do something with the list .. the list is all good

} 

public IAuthorizationState GetAuthorization(NativeApplicationClient client)
{
        // You should use a more secure way of storing the key here as
        // .NET applications can be disassembled using a reflection tool.
        const string STORAGE = "google.samples.dotnet.calendar";
        const string KEY = "s0mekey";

        // Check if there is a cached refresh token available.
        IAuthorizationState state = AuthorizationMgr.GetCachedRefreshToken(STORAGE, KEY);
        if ((state != null))
        {
            try
            {
                client.RefreshToken(state);
                return state;
                // we are done
            }
            catch (DotNetOpenAuth.Messaging.ProtocolException ex)
            {
                CommandLine.WriteError("Using an existing refresh token failed: " + ex.Message);
                CommandLine.WriteLine();
            }
        }

        // Retrieve the authorization from the user
        string[] array = new string[scopes.Count];
        scopes.CopyTo(array,0);
        state = AuthorizationMgr.RequestNativeAuthorization(client, array);
        AuthorizationMgr.SetCachedRefreshToken(STORAGE, KEY, state);
        return state;
} 

How can I use the similar OAuth2Authenticator to fetch Contacts? 如何使用类似的OAuth2Authenticator来获取联系人?

I am able to fetch contacts using the below code, but its not password-less, I need to get it working using Oath2. 我可以使用下面的代码获取联系人,但它不是密码,我需要使用Oath2使其工作。 The example below uses Gdata contacts api v2. 以下示例使用Gdata联系人api v2。 I can see that i can pass through OAuth2Authenticator but im not exactly sure how to do it correctly (i cant see any valid examples in C# on the google site) and fetch the access code based on what the user is selecting. 我可以看到我可以通过OAuth2Authenticator,但我不确定如何正确地做到这一点(我无法在谷歌网站上看到C#中的任何有效示例)并根据用户选择的内容获取访问代码。 I cant see how to use OAuth2Authenticator with the contacts api v3 ( https://developers.google.com/google-apps/contacts/v3/ ) 我无法看到如何将OAuth2Authenticator与联系人api v3一起使用( https://developers.google.com/google-apps/contacts/v3/

RequestSettings rsLoginInfo = new RequestSettings("", email,pwd);
rsLoginInfo.AutoPaging = true;
ContactsRequest cRequest = new ContactsRequest(rsLoginInfo);

// fetch contacts list
Feed<Contact> feedContacts = cRequest.GetContacts();
foreach (Contact gmailAddresses in feedContacts.Entries)
{
        // Looping to read  email addresses
        foreach (EMail emailId in gmailAddresses.Emails)
        {
           lstContacts.Add(emailId.Address);
        }
}

I ended up doing this by fetching the access code by having a browser control read the Document title value when the user selects the google account and grants access. 我最后通过在用户选择Google帐户并授予访问权限时让浏览器控件读取文档标题值来获取访问代码。

eg: 例如:

To Generate URL 生成URL

RedirectURI = "urn:ietf:wg:oauth:2.0:oob"

OAuth2Parameters parameters = new OAuth2Parameters()
{
    ClientId = clientId,
    ClientSecret = clientSecret,
    RedirectUri = redirectUri,
    Scope = requiredScope
};


// Request authorization from the user (by opening a browser window):
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
var loginUri = new Uri(url);

// This form has browser control
GoogleLoginForm form = new GoogleLoginForm(loginUri, redirectUri);
var dr = form.ShowDialog();

if (dr == System.Windows.Forms.DialogResult.OK)
{
    parameters.AccessCode = form.OAuthVerifierToken;
}

Then In GoogleLoginForm : We have a browser control and registered browserControl_Navigated event and the do the below. 然后在GoogleLoginForm中:我们有一个浏览器控件并注册了browserControl_Navigated事件并执行以下操作。 The DocumentTitle contains the AccessCode which is used to generate the token. DocumentTitle包含用于生成令牌的AccessCode。

private void GoogleLoginForm_Load(object sender, EventArgs e)
{
   wbGoogleLogin.Url = _loginUri;
}

private void wbGoogleLogin_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    string fullPath = e.Url.ToString();
    WebBrowser control = sender as WebBrowser;
    if (control != null &&  !string.IsNullOrEmpty(control.DocumentTitle) && control.DocumentTitle.Contains("Success code"))
    {
       _OAuthVerifierToken = control.DocumentTitle.Replace("Success code=","");
       DialogResult = DialogResult.OK;
    }
}

This way it can be done in the same piece of code, without having to write a complicated callback service of some sort to read the access token back into our system. 这样就可以在同一段代码中完成,而无需编写某种复杂的回调服务来将访问令牌读回到我们的系统中。

Not exactly sure why the calendar api has this built in, and the contacts API doesn't. 不完全确定为什么日历api内置了这个,而联系人API没有。

Firstly, the quick answer to your question. 首先,快速回答您的问题。 I believe that the IAuthorizationState has similar properties to OAuth2Parameters. 我相信IAuthorizationState具有与OAuth2Parameters类似的属性。 Thus, you should be able to do this (combining it with the code you have for the calender): 因此,您应该能够这样做(将它与您对日历的代码结合起来):

OAuth2Authenticator<NativeApplicationClient> auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);

//This will call your GetAuthorization method
auth.LoadAccessToken()
RequestSettings settings = new RequestSettings("appName", auth.State.AccessToken);
ContactsRequest cRequest = new ContactsRequest(settings);

// fetch contacts list
Feed<Contact> feedContacts = cRequest.GetContacts();
foreach (Contact gmailAddresses in feedContacts.Entries)
{
        // Looping to read  email addresses
        foreach (EMail emailId in gmailAddresses.Emails)
        {
           lstContacts.Add(emailId.Address);
        }
}

This should work as the RequestSettings allows you to specify an access token. 这应该起作用,因为RequestSettings允许您指定访问令牌。 That being said, I myself prefer to use : 话虽这么说,我自己更喜欢使用:

var parameters = new OAuth2Parameters()
{
    //Client 
    ClientId = CLIENT_ID,
    ClientSecret = CLIENT_SECRET,
    RedirectUri = redirectUri,
    Scope = "https://www.google.com/m8/feeds",
    ResponseType = "code"
};

//User clicks this auth url and will then be sent to your redirect url with a code parameter
var authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
.
.
.
//using the code parameter
parameters.AccessCode = code;
OAuthUtil.GetAccessToken(parameters);
var settings = new RequestSettings(applicationName, parameters);
var cr = new ContactsRequest(settings);
//Now you can use contacts as you would have before

Although, Ive only tested this with Web Server Apps, so maybe the authenticator is needed for your situation? 虽然,我只使用Web服务器应用程序对此进行了测试,因此您的情况可能需要验证器吗? I found these source codes handy: 我发现这些源代码很方便:

OAuth2Demo OAuth2Demo

IAuthorizationState IAuthorizationState

OAuth2Authenticator OAuth2Authenticator

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM