配置 OAuth 2.0 API 访问 Google 服务
创建 Google 开发者控制台项目以访问 API
在 Google 开发者控制台中创建项目是访问和使用 Google API 的关键步骤。此过程包括创建项目、同意条款、验证身份以及配置 API 设置以满足需求。以下步骤将指导您完成创建项目并获取 Calendar 和 Contacts API 等服务所需凭据的过程。
在 Google 开发者控制台中创建项目的步骤
- 访问链接 https://cloud.google.com/console/project 并使用您的 Gmail 凭据登录
![]() |
|---|
- 选中复选框 “I have read and agree to all Terms of Service for the Google Cloud Platform products.” 并点击 Create 按钮
![]() |
|---|
- 将请求 “SMS Verification”。点击继续按钮:
![]() |
|---|
- 输入您的国家名称和手机号码。点击按钮:发送验证码
![]() |
|---|
- 输入在手机上收到的验证码。
![]() |
|---|
- 在 APIs & auth \ APIs 列表中,打开 Calendar API 和 Contacts API 的状态,关闭其他所有 API。
![]() |
|---|
- 在 APIs & auth -> Credentials 中,点击 “OAuth” 部分下的 “CREAET NEW CLIENT ID” 按钮。选择 “Installed application” 并选择 “Other”,然后点击 “Create Client ID” 按钮。记录下此处的 Client ID 和 Client Secret,它们将在本节的示例代码中使用。
![]() |
|---|
安全的 Google OAuth 2.0 集成
在 Aspose.Email for .NET 中使用 Google OAuth 2.0 时,需要以下类:
-
GoogleOAuthHelper 类 - 简化了对 Google 用户进行身份验证并获取与 Google API(如 Calendar、Contacts、Gmail)交互所需令牌的过程。
-
GoogleUser 类 - 旨在封装和管理用户进行身份验证并与 Google 服务交互所需的凭据,特别是需要 OAuth 2.0 身份验证的 API,如 Google Calendar。
-
TokenResponse 类 - 该模型用于表示和处理来自 OAuth 2.0 令牌端点的响应数据,在此处可通过授权获取访问令牌。
在以下文章中,您将找到代码示例,演示如何在 .NET 环境中使用这些类,以建立与 OAuth 2.0 服务的安全交互。
使用 GoogleOAuthHelper 类进行 OAuth 2.0 身份验证
该类处理授权码 URL 的创建、代码挑战的生成以及访问令牌和刷新令牌的获取。通过使用 GoogleOAuthHelper,开发者可以简化 OAuth 2.0 流程,确保与 Google 服务的安全高效通信。以下代码片段展示了如何实现 GoogleOAuthHelper 类到项目中:
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
/// <summary>
/// Developer console:
/// https://console.cloud.google.com/projectselector2
/// Documentation:
/// https://developers.google.com/identity/protocols/oauth2/native-app
/// </summary>
internal class GoogleOAuthHelper
{
public const string AUTHORIZATION_URL = "https://accounts.google.com/o/oauth2/v2/auth";
public const string TOKEN_REQUEST_URL = "https://oauth2.googleapis.com/token";
public const string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
public const string REDIRECT_TYPE = "code";
public static string codeVerifier;
public static string codeChallenge;
public static CodeChallengeMethod codeChallengeMethod = CodeChallengeMethod.S256;
public const string SCOPE =
"https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar" + // Calendar
"+" +
"https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F" + // Contacts
"+" +
"https%3A%2F%2Fmail.google.com%2F"; // IMAP & SMTP
static GoogleOAuthHelper()
{
CreateCodeVerifier();
CreateCodeChallenge();
}
internal static string CreateCodeVerifier()
{
string allowedChars = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-._~";
const int minLength = 43;
const int maxLength = 128;
Random random = new Random();
int length = minLength + random.Next(maxLength - minLength);
List<char> codeVerifierChars = new List<char>();
for (int i = 0; i < length; i++)
{
int index = random.Next(allowedChars.Length);
codeVerifierChars.Add(allowedChars[index]);
}
return codeVerifier = string.Join("", codeVerifierChars.ToArray());
}
internal static string CreateCodeChallenge()
{
if (codeChallengeMethod == CodeChallengeMethod.Plain)
return codeChallenge = codeVerifier;
byte[] hashValue = null;
using (SHA256 sha256 = SHA256.Create())
hashValue = sha256.ComputeHash(Encoding.ASCII.GetBytes(codeVerifier));
string b64 = Convert.ToBase64String(hashValue);
b64 = b64.Split('=')[0];
b64 = b64.Replace('+', '-');
b64 = b64.Replace('/', '_');
return codeChallenge = b64;
}
internal static string GetAuthorizationCodeUrl(GoogleUser user)
{
return GetAuthorizationCodeUrl(user, SCOPE, REDIRECT_URI, REDIRECT_TYPE);
}
internal static string GetAuthorizationCodeUrl(
GoogleUser user, string scope, string redirectUri, string responseType)
{
string state = System.Web.HttpUtility.UrlEncode(Guid.NewGuid().ToString());
string approveUrl = AUTHORIZATION_URL +
$"?client_id={user.ClientId}&redirect_uri={redirectUri}&response_type={responseType}&scope={scope}&" +
$"code_challenge={codeChallenge}&code_challenge_method={codeChallengeMethod.ToString()}&" +
$"state={state}";
return approveUrl;
}
internal static TokenResponse GetAccessTokenByRefreshToken(GoogleUser user)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(TOKEN_REQUEST_URL);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string clientId = System.Web.HttpUtility.UrlEncode(user.ClientId);
string clientSecret = System.Web.HttpUtility.UrlEncode(user.ClientSecret);
string refreshToken = System.Web.HttpUtility.UrlEncode(user.RefreshToken);
string grantType = System.Web.HttpUtility.UrlEncode("refresh_token");
string encodedParameters = $"client_id={clientId}&client_secret={clientSecret}&refresh_token={refreshToken}&grant_type={grantType}";
byte[] requestData = Encoding.UTF8.GetBytes(encodedParameters);
request.ContentLength = requestData.Length;
if (requestData.Length > 0)
using (Stream stream = request.GetRequestStream())
stream.Write(requestData, 0, requestData.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string responseText = null;
using (TextReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
responseText = reader.ReadToEnd();
TokenResponse tokensResponse = JsonConvert.DeserializeObject<TokenResponse>(responseText);
return tokensResponse;
}
internal static TokenResponse GetAccessTokenByAuthCode(string authorizationCode, GoogleUser user)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(TOKEN_REQUEST_URL);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string clientId = System.Web.HttpUtility.UrlEncode(user.ClientId);
string clientSecret = System.Web.HttpUtility.UrlEncode(user.ClientSecret);
string authCode = System.Web.HttpUtility.UrlEncode(authorizationCode);
string redirectUri = System.Web.HttpUtility.UrlEncode(REDIRECT_URI);
string grantType = System.Web.HttpUtility.UrlEncode("authorization_code");
string encodedParameters = $"client_id={clientId}&client_secret={clientSecret}&code={authCode}&code_verifier={codeVerifier}&redirect_uri={redirectUri}&grant_type={grantType}";
byte[] requestData = Encoding.UTF8.GetBytes(encodedParameters);
request.ContentLength = requestData.Length;
if (requestData.Length > 0)
using (Stream stream = request.GetRequestStream())
stream.Write(requestData, 0, requestData.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string responseText = null;
using (TextReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
responseText = reader.ReadToEnd();
TokenResponse tokensResponse = JsonConvert.DeserializeObject<TokenResponse>(responseText);
return tokensResponse;
}
public enum CodeChallengeMethod
{
S256,
Plain
}
}
Google OAuth Helper 应按如下方式使用:
- 首先需要生成授权码 URL。
- 在浏览器中打开 URL 并完成所有操作。随后,您将收到授权码。
- 使用授权码获取刷新令牌。
- 当刷新令牌存在时,可使用它检索访问令牌。
GoogleUser user = new GoogleUser(email, password, clientId, clientSecret);
string authUrl = GoogleOAuthHelper.GetAuthorizationCodeUrl(user);
Console.WriteLine("Go to the following URL and get your authorization code:");
Console.WriteLine(authUrl);
Console.WriteLine();
Console.WriteLine("Enter the authorization code:");
string authorizationCode = Console.ReadLine();
Console.WriteLine();
TokenResponse tokenInfo = GoogleOAuthHelper.GetAccessTokenByAuthCode(authorizationCode, user);
Console.WriteLine("The refresh token has been received:");
Console.WriteLine(tokenInfo.RefreshToken);
Console.WriteLine();
user.RefreshToken = tokenInfo.RefreshToken;
tokenInfo = GoogleOAuthHelper.GetAccessTokenByRefreshToken(user);
Console.WriteLine("The new access token has been received:");
Console.WriteLine(tokenInfo.AccessToken);
Console.WriteLine();
OAuth 2.0 身份验证的 GoogleUser 类
以下代码片段展示了如何实现 GoogleUser 类:
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
public class GoogleUser
{
public GoogleUser(string email, string password, string clientId, string clientSecret)
: this(email, password, clientId, clientSecret, null)
{
}
public GoogleUser(string email, string password, string clientId, string clientSecret, string refreshToken)
{
Email = email;
Password = password;
ClientId = clientId;
ClientSecret = clientSecret;
RefreshToken = refreshToken;
}
public readonly string Email;
public readonly string Password;
public readonly string ClientId;
public readonly string ClientSecret;
public string RefreshToken;
}
使用 TokenResponse 类进行 OAuth 2.0 身份验证
以下代码片段展示了如何 TokenResponse 可以实现类:
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
using Newtonsoft.Json;
public class TokenResponse
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "access_token", Required = Required.Default)]
public string AccessToken { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "token_type", Required = Required.Default)]
public string TokenType { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "expires_in", Required = Required.Default)]
public int ExpiresIn { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "refresh_token", Required = Required.Default)]
public string RefreshToken { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "scope", Required = Required.Default)]
public string Scope { get; set; }
}






