c# - 如何在 C# 中为 Google AutoML 获取 OAuth 2.0 身份验证承载令牌?
问题描述
以下代码从 google 抛出返回响应,缺少必需的参数:response_type。该错误可能会误导其他内容,或者该值可能是错误的。这是文档:https ://cloud.google.com/docs/authentication/#oauth-2.0-clients
var client = new RestClient("https://accounts.google.com/o/oauth2/auth");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&client_id=501819637859-6ng1c949htt0admmpa19vm6tfle04jdc.apps.googleusercontent.com&client_secret=nrrIjxFqugLKd24E8xVesA6f", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
解决方案
是的,可以编写您自己的 Google Oauth2 流版本。
第一次通话
第一个调用是 HTTP GET,是向用户显示的同意屏幕的链接。
如果这是已安装的应用程序,例如桌面应用程序或控制台应用程序。然后重定向 uri 应该是 urn:ietf:wg:oauth:2.0:oob。
如果您想要多个范围,则应以空格分隔,如果您想取回刷新令牌,请添加离线。
GET https://accounts.google.com/o/oauth2/v2/auth?client_id={clientid}&redirect_uri={RedirectURI}&scope={scopes}&response_type=code
第二次通话
第一次调用的响应是验证码,此码需要与谷歌交换。这是一个 HTTP POST
POST https://oauth2.googleapis.com/token
code=4/X9lG6uWd8-MMJPElWggHZRzyFKtp.QubAT_P-GEwePvB8fYmgkJzntDnaiAI&client_id=
{ClientId}&client_secret={ClientSecret}&redirect_uri={RedirectURI}&grant_type=authorization_code
此调用的发布数据是一个长字符串,请勿尝试解析它。只需将其发布在您的通话正文中即可。内容类型是“application/x-www-form-urlencoded”是正确的;
此调用的响应将包含访问令牌和刷新令牌
{
"access_token" : "ya29.1.AADtN_VSBMC2Ga2lhxsTKjVQ_ROco8VbD6h01aj4PcKHLm6qvHbNtn-_BIzXMw",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/J-3zPA8XR1o_cXebV9sDKn_f5MTqaFhKFxH-3PUPiJ4"
}
访问令牌将在一小时后过期,因此您需要刷新它,这就是刷新令牌的用途。
刷新访问令牌
下面的调用也是一个 HTTP POST
https://oauth2.googleapis.com/token
client_id={ClientId}&client_secret={ClientSecret}&refresh_token={Refresh token from previous call}&grant_type=refresh_token
工作示例
class Program
{
private const string Clientid = "Add yours";
private const string Secret = "Add yours.";
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.WriteLine($"open the following link in your browser window: {Helper.BuildConsentURL(Clientid, new []{ "profile" })}");
Console.WriteLine("Please paste the Authorization code here:");
var authorizationCode = Console.ReadLine();
var tokenResponse = await Helper.ExchangeAuthorizationCode(authorizationCode, Clientid, Secret);
var refreshTokenResponse = await Helper.ExchangeRefreshToken(tokenResponse.refresh_token, Clientid, Secret);
}
}
助手.cs
public class Helper
{
/// <summary>
///
/// </summary>
/// <param name="clientId"></param>
/// <param name="scope">string array of scopes</param>
/// <param name="redirectUri">leave empty for installed application</param>
/// <returns></returns>
public static string BuildConsentURL(string clientId, string[] scope, string redirectUri = null)
{
if (string.IsNullOrEmpty(redirectUri))
{
redirectUri = "urn:ietf:wg:oauth:2.0:oob"; // for installed application
}
return
$"https://accounts.google.com/o/oauth2/auth?client_id={clientId}&redirect_uri={redirectUri}&scope={string.Join(" ", scope)}&response_type=code";
}
private static string BuildAuthorizationCodeRequest(string code, string clientId, string secret,
string redirectUri)
{
return
$"code={code}&client_id={clientId}&client_secret={secret}&redirect_uri={redirectUri}&grant_type=authorization_code";
}
private static string BuildRefreshAccessTokenRequest(string refreshToken, string clientId, string secret)
{
return
$"client_id={clientId}&client_secret={secret}&refresh_token={refreshToken}&grant_type=refresh_token";
}
private static async Task<AuthResponse> PostMessage(string postData)
{
AuthResponse result;
var client = new HttpClient();
client.BaseAddress = new Uri("https://accounts.google.com/");
var request = new HttpRequestMessage(HttpMethod.Post, "o/oauth2/token");
request.Content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.SendAsync(request);
using (var content = response.Content)
{
var json = content.ReadAsStringAsync().Result;
result = JsonSerializer.Deserialize<AuthResponse>(json);
}
return result;
}
public static async Task<AuthResponse> ExchangeAuthorizationCode(string code, string clientId, string secret,
string redirectUri = null)
{
var result = new AuthResponse();
if (string.IsNullOrEmpty(redirectUri))
{
redirectUri = "urn:ietf:wg:oauth:2.0:oob"; // for installed application
}
var postData = BuildAuthorizationCodeRequest(code, clientId, secret, redirectUri);
return await PostMessage(postData);
}
public static async Task<AuthResponse> ExchangeRefreshToken(string refreshToken, string clientId, string secret)
{
var postData = BuildRefreshAccessTokenRequest(refreshToken, clientId, secret);
return await PostMessage(postData);
}
}
Authressonse.cs
public class AuthResponse
{
public string access_token { get; set; }
public string token_type { get; set; }
public int expires_in { get; set; }
public string refresh_token { get; set; }
}
推荐阅读
- active-directory - Spring Security LDAP:在 ApacheDS 中针对 Active Directory 进行绑定与身份验证
- python - Python - 使用正则表达式从字段中提取文本
- html5-canvas - 当 SVG 包含具有自定义字体的文本时,FabricJS 无法正确渲染 SVG?
- java - JAVA_HOME的配置
- machine-learning - 我的问题属于机器学习还是深度学习的哪一类?
- php - 如何连接多个表,返回第一个表(file_id),第二个表是 file_list(file_no)?
- python - AttributeError: 'timedelta' 对象在 Form1 第 38 行没有属性 'strptime'
- logging - TensorWatch 相对于 TensorBoardX 的优势?
- javascript - 正则表达式匹配模式,后跟 /,然后是一组特定的单词
- python - 减法和乘法列