4

我有以下代码来使用使用 OAuth2的谷歌日历 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);
        }
}
4

2 回答 2

4

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

例如:

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

然后在 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 没有。

于 2013-09-06T01:16:15.413 回答
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

授权状态

OAuth2身份验证器

于 2013-08-28T15:36:45.123 回答