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

时间:2013-08-16 01:10:26

标签: c# .net google-api oauth-2.0

我在下面的代码中使用使用OAuth2的Google Calendar API(https://developers.google.com/google-apps/calendar/)获取日历条目。 它运作良好。

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

如何使用类似的OAuth2Authenticator来获取联系人?

我可以使用下面的代码获取联系人,但它不是无密码,我需要使用Oath2让它工作。以下示例使用Gdata联系人api v2。我可以看到我可以通过OAuth2Authenticator,但我不确定如何正确地做到这一点(我无法在谷歌网站上看到C#中的任何有效示例)并根据用户选择的内容获取访问代码。 我无法看到如何使用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);
        }
}

2 个答案:

答案 0 :(得分:4)

我最后通过在用户选择Google帐户并授予访问权限时让浏览器控件读取文档标题值来获取访问代码。

例如:

生成网址

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

然后在GoogleLoginForm中: 我们有一个浏览器控件和注册的browserControl_Navigated事件,并执行以下操作。 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;
    }
}

这种方式可以在同一段代码中完成,而无需编写某种复杂的回调服务来将访问令牌读回我们的系统。

不完全确定为什么日历api内置了这个,而联系人API没有。

答案 1 :(得分:2)

首先,快速回答您的问题。我相信IAuthorizationState具有与OAuth2Parameters类似的属性。因此,您应该能够这样做(将它与您对日历的代码相结合):

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

这应该起作用,因为RequestSettings允许您指定访问令牌。话虽这么说,我自己更喜欢使用:

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

虽然,我只使用Web服务器应用程序对此进行了测试,因此您的情况可能需要验证器吗?我发现这些源代码很方便:

OAuth2Demo

IAuthorizationState

OAuth2Authenticator