如何在 .Net Core 控制台应用程序中为 OAuth 2.0 同意屏幕生成授权 URL?

How to generate authorization URL for OAuth 2.0 consent screen in .Net Core Console Application?

我知道可以通过 裸控制台应用程序 中已弃用的 Google.GData.Client 库在 .net 框架内生成 OAuth2.0 同意屏幕 URL ].流程如下所示:

// OAuth2Parameters object, which holds all the parameters related to OAuth 2.0.
OAuth2Parameters parameters = new OAuth2Parameters();

// Set OAuth 2.0 Client Id
parameters.ClientId = clientId;

// Set  OAuth 2.0 Client Secret
parameters.ClientSecret = clientSecret;

// Set Redirect URI (in this case it will return authorization code in browser)
parameters.RedirectUri = "urn:ietf:wg:oauth:2.0:oob";

// Set Desired Scope.
parameters.Scope = scope;

// desired URL via OAuthUtil's static method
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);

这个 URL 我可以在浏览器中打开,查看 Google 同意屏幕,单击允许并检索授权代码,然后我将使用它来获取适当的访问权限和刷新令牌 像这样:

parameters.AccessCode = Console.ReadLine();
OAuthUtil.GetAccessToken(parameters);
accessToken = parameters.AccessToken;
refreshToken = parameters.RefreshToken;

我的主要问题是我想在 裸 .Net Core 控制台应用程序(当然没有 GData)中执行此操作,但我很难找到方法。我想,一般情况下可以这样做,至少 PHP、Ruby 和 Python 的活跃示例至少可以为 打电话给 YouTube API。有人可能知道如何在 .Net Core 中执行此操作吗?

此外,这无法通过服务帐户处理(我在我的应用程序中没有问题),因为用户可能不是来自我的组织,所以看起来有必要查看同意屏幕。

Oauth2 流程。

Oauth2 实际上很容易处理,您只需要能够执行 HTTP GET 和 HTTP Post 调用即可。

我们要做的第一件事是创建 link 来显示同意屏幕。这是一个 HTTP Get 调用,因此可以放在任何 Web 浏览器中。

https://accounts.google.com/o/oauth2/v2/auth?client_id=XXXX.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/userinfo.profile&response_type=code

当用户同意访问时,授权码将显示在页面上。

接下来您需要做的是将该授权码交换为访问令牌和刷新令牌。

这是一个 HTTP POST 调用,您可以使用 .net core 轻松完成这里是使用 Curl

的调用示例
curl -s \
--request POST \
--data "code=4/1AY0e-g7BhBt0QU9f5HTgNDGNR1GYtH12q4xvgL_D2Q34A&client_id=XXXX.apps.googleusercontent.com&client_secret=zYAoXDam3mqsdwabh3dQ3NTh&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code" \
https://accounts.google.com/o/oauth2/token 

此时服务器会return给你一个访问令牌

{
  "access_token": "ya29.a0AfH6SMDypscIeiyNnPRvoizz3NvvA6SZdk9U4K8h4MyQRRm29kEc2shdrskPZp71Q1roy8RqIm_7spufW84ozUoSTk0QKkQ",
  "expires_in": 3599,
  "refresh_token": "1//09Y5LQ0XRxjt-CgYIARAAGAkSNwF-L9IrYzyMnbGtJHgh-FTf6z79cBhQ1hsPUAk71HFgFwqyXoiwpIa-4eA",
  "scope": "https://www.googleapis.com/auth/userinfo.profile",
  "token_type": "Bearer"
}

如果你想知道它是如何工作的,我这里有一个视频Understanding Oauth2 with curl companion blog post How to get a Google access token with CURL

google .net 客户端库

我强烈建议您使用 Google .net clinet library 支持 .net 核心。

以下是已安装应用程序(控制台应用程序)的授权示例。

    /// <summary>
    /// ** Installed Application only ** 
    /// 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>
    /// <param name="scopes">Array of Google scopes</param>
    /// <returns>authencated UserCredential</returns>
    private static UserCredential GetUserCredential(string clientSecretJson, string userName, string[] scopes)
    {
        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               
            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
                var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                                                                         scopes,
                                                                         userName,
                                                                         CancellationToken.None,
                                                                         new FileDataStore(credPath, true)).Result;

                credential.GetAccessTokenForRequestAsync();
                return credential;
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Get user credentials failed.", ex);
        }
    }

我的网站 Daimto.com and my YouTube channel Daimto developer tips Have examples for using the google apis with .net. I also have a github project Google-Dotnet-Samples 包含大多数 API 的示例。