在我有access_token之前,Google Api需要userId

时间:2017-01-26 13:16:00

标签: .net google-api google-oauth google-api-dotnet-client

我收到了authorization code,想要将其与服务器上的authorization token交换。 .NET API API在流类中有ExchangeCodeForTokenAsync方法。看起来像我需要但它需要userId作为其参数之一。

var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = new ClientSecrets
            {
                ClientId = "...",
                ClientSecret = "..."
            },
            Scopes = new[] { "some scopes" },
        });

flow.ExchangeCodeForTokenAsync(userId, code, "redirect url", CancellationToken.None); //exchange token requires userId

我应该在收到授权令牌之前注册用户吗?但在我获取他的Google个人资料信息之前我无法做到(我需要一个令牌)。

不幸的是,没有.NET客户端的文档,但documentation for other languages(搜索"在Web服务器收到授权代码后#34;在页面上访问相关部分)不提userId。

所以要么我试图使用错误的方法,要么.NET Api是错误的,或者我只是错过了一些明显的东西。

3 个答案:

答案 0 :(得分:1)

让我们从获取用户的个人资料信息开始。

您可以为此People API和Google + API使用两种API。

以下方法将请求用户访问。通过发送不同的用户名来更改每个用户,然后将凭据信息存储在%appData%中,您可以阅读有关此here的更多信息

    /// <summary>
    /// This method requests Authentcation from a user using Oauth2.  
    /// Credentials are stored in System.Environment.SpecialFolder.Personal
    /// Documentation https://developers.google.com/accounts/docs/OAuth2
    /// </summary>
    /// <param name="clientSecretJson">Path to the client secret json file from Google Developers console.</param>
    /// <param name="userName">Identifying string for the user who is being authentcated.</param>
    /// <returns>DriveService used to make requests against the Drive API</returns>
    public static PeopleService AuthenticateOauth(string clientSecretJson, string userName)
    {
        try
        {
            if (string.IsNullOrEmpty(userName))
                throw new ArgumentNullException("userName");
            if (string.IsNullOrEmpty(clientSecretJson))
                throw new ArgumentNullException("clientSecretJson");
            if (!File.Exists(clientSecretJson))
                throw new Exception("clientSecretJson file does not exist.");

            // These are the scopes of permissions you need. It is best to request only what you need and not all of them
            string[] scopes = new string[] { PeopleService.Scope.UserPhonenumbersRead,  //View your phone numbers
                                             PeopleService.Scope.UserAddressesRead,     //View your street addresses
                                             PeopleService.Scope.UserBirthdayRead,      //View your complete date of birth
                                             PeopleService.Scope.ContactsReadonly,      //View your contacts
                                             PeopleService.Scope.UserEmailsRead,        //View your email addresses
                                             PeopleService.Scope.UserinfoProfile,       //View your basic profile info
                                             PeopleService.Scope.UserinfoEmail,         //View your email address
                                             PeopleService.Scope.PlusLogin,             //Know your basic profile info and list of people in your circles.
                                             PeopleService.Scope.Contacts};             //Manage your contacts
            UserCredential credential;
            using (var stream = new FileStream(clientSecretJson, FileMode.Open, FileAccess.Read))
            {
                string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);

                // Requesting Authentication or loading previously stored authentication for userName
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                                                                         scopes,
                                                                         userName,
                                                                         CancellationToken.None,
                                                                         new FileDataStore(credPath, true)).Result;
            }

            // Create Drive API service.
            return new PeopleService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "People Oauth2 Authentication Sample"
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine("Create Oauth2 account PeopleService failed" + ex.Message);
            throw new Exception("CreateServiceAccountPeopleFailed", ex);
        }
    }

这将返回一个PeopleService,您可以使用它来向人们api发出请求。就像向用户请求数据一样。

  

var me = service.People.Get(&#34; people / me&#34;)。执行();

您可以将谷歌日历范围添加到其中,您的用户指南将有利于谷歌人员服务和谷歌日历服务。

我也有一些谷歌日历here的示例代码。

更新javascript问题:

JavaScript不包含只有访问令牌的刷新令牌。 FileDatastore无法理解这一点。您可能需要自己实现idatastore。我的问题是你打算如何处理访问令牌到期时你是否要回复你的JavaScript授权代码?

答案 1 :(得分:1)

我浏览了AuthorizationCodeFlow source code,虽然userId未用于Google Api请求(如预期的那样),但它用于将结果存储到DataStore。因此,如果您只是使用api调用结果,则可能无法传递userId,否则您必须拥有它。

答案 2 :(得分:0)

要通过access_token交换授权码,您需要from the docs

  1. code - 初始请求返回的授权码。
  2. client_id - 从API控制台获取的客户端ID。
  3. client_secret - 从API控制台获取的客户端密钥。
  4. redirect_uri - 在API控制台中为此项目列出的重定向URI之一。
  5. grant_type - 根据OAuth 2.0规范的定义,此字段必须包含authorization_code值。
  6. 也许您说的是期望userIdclient_id ...我不知道图书馆...如果说假设有一个userId而不是client_id,则可能是一个错误这个ExchangeCodeForTokenAsync方法。