Google C# 中的身份工具包 API
Google Identity Toolkit API in C#
一些背景信息
我正在使用 C# 在 Unity 中构建游戏。由于我使用的是 Firebase,而 ready-made Unity Firebase SDK 不适用于我的情况 1,因此我求助于 Firebase's REST API through C#'s HttpClient
class 接口(附带 System.Net.Http
)。
我目前正在努力使用 Firebase 身份验证 API。对于那些不熟悉 OAuth APIs 的人,当我调用 Sign Up 或 Sign In 端点时,我得到了一个 ID Token 和一个 Refresh Token。 ID 令牌过期;刷新令牌没有。当 ID 令牌过期时,我必须调用另一个端点,称为 令牌交换,以使用我的刷新令牌获取新的 ID 令牌。
1 There is a rumored Google Identity Toolkit C# library, but the first result returned by that search I found it by leads to a 404 error instead of documentation.
什么有效
在 Firebase guides and the underlying Identity Toolkit guides 之后,到目前为止,我已成功将令牌交换端点与来自 bash 的 cURL
命令连接:
curl 'https://securetoken.googleapis.com/v1/token?key=[MY FIREBASE API KEY]' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=refresh_token&refresh_token=[MY REFRESH TOKEN]'
当然,我将 [MY FIREBASE API KEY]
替换为我的 Firebase Web API 密钥,并将 [MY REFRESH TOKEN]
替换为从符号 in/sign 向上端点返回的刷新令牌。
然而,尽管我进行了多次尝试,但我无法在 C# 中复制此 cURL
命令!
我失败的尝试
1.
这是我的原始代码,但它不起作用。
public async Task<bool> ExchangeToken()
{
FormUrlEncodedContent body = new FormUrlEncodedContent(new Dictionary<string, string>() {
{"grant_type", "refresh_token" },
{"refresh_token", Uri.EscapeDataString(user.refreshToken) }
});
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, "https://securetoken.googleapis.com/v1/token?key=" + apiKey);
message.Content = body;
message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
HttpResponseMessage res = await client.SendAsync(message);
}
不幸的是,我收到此 401 (Unauthorized)
错误响应:
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
这很奇怪,考虑到我从应该是等效的 cURL
命令得到 2XX (OK)
响应...
2.
感谢 very nice website 我刚刚发现,我能够 "convert" 我的 cURL
命令进入 C# 代码。但是,这没有用。我得到了与尝试 #1 完全相同的错误。
public async Task<bool> ExchangeToken()
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://securetoken.googleapis.com/v1/token?key=[I WOULD INSERT MY KEY HERE]"))
{
request.Content = new StringContent("grant_type=refresh_token&refresh_token=[INSERT REFRESH TOKEN HERE]", Encoding.UTF8, "application/x-www-form-urlencoded");
var res = await client.SendAsync(request);
}
}
可能的线索
- 我对所有其他端点的所有其他请求都有效。有两个显着差异:1) API 在技术上不是 Firebase 的,而是 Google Identity Toolkit 的。 2) 这是我使用的唯一端点,它使用
application/x-www-form-urlencoded
的 Content-Type
header 而不是 application/json
。
我的问题/TL;DR
How do I interface with the Google Identity Toolkit API's Token Exchange endpoint using C#?
(Though I'm currently using the HttpClient class, I'm totally open to other solutions! They just have to be compatible with Unity3D.)
提前致谢!
Google 希望您使用 Firebase 进行身份验证。虽然 Firebase 没有 Google 提供的 .NET 客户端 SDK,但有 .
如果您不使用 Firebase 并使用 oAuth/OpenID 自己连接端点来执行必要的任务,那也可以。有一个 Google .NET SDK 可以帮助您解决这个问题……一点点。 SDK 列出了 Google 个被 SDK "supported" 的 API; Google Cloud Identity v1
和 v1beta
API 都在列表中。因此,您可以通过此 .NET SDK 调用 Google Cloud Identity 端点。您确实必须了解各种身份验证流程的含义,而在 Firebase 中,作为应用程序开发人员,大部分机制都是从您那里抽象出来的。
在仔细研究了代码之后,我记得我在 HttpClient
上设置了默认授权:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", idToken);
这已包含在所有其他 API 调用中,因为它们需要使用 ID 令牌进行身份验证。但是,这似乎混淆了令牌交换端点;它必须 1) 寻找授权 header, 然后 2) 使用刷新消息内容中提供的令牌。
如何解决这个问题
- 不要在
HttpClient
上设置默认值 header(它应该被重用于 所有 的 HTTP 请求),而是执行以下操作:
var req = new HttpRequestMessage(/* HttpMethod enum value, endpoint URL/IP */);
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", user.idToken); //Set the authorization per-request, not globally
var res = await client.SendAsync(req);
- 然后只需调用令牌交换端点即可!
来自Firebase REST API Documentation:
You can refresh a Firebase ID token by issuing an HTTP POST request to the securetoken.googleapis.com endpoint.
https://securetoken.googleapis.com/v1/token?key=[API_KEY]
只需在 body 中提供一个 refresh_token
参数(以及值为 refresh_token
的强制性 grant_type
)。 请勿提供授权header。
希望这对遇到同样问题的人有所帮助!
作为替代方案,您还可以使用 https://github.com/google/apis-client-generator 从发现文档生成 c# 客户端。我在生成我的文件时遇到了一些命名冲突,但在解决这些冲突之后就可以了。
一些背景信息
我正在使用 C# 在 Unity 中构建游戏。由于我使用的是 Firebase,而 ready-made Unity Firebase SDK 不适用于我的情况 1,因此我求助于 Firebase's REST API through C#'s HttpClient
class 接口(附带 System.Net.Http
)。
我目前正在努力使用 Firebase 身份验证 API。对于那些不熟悉 OAuth APIs 的人,当我调用 Sign Up 或 Sign In 端点时,我得到了一个 ID Token 和一个 Refresh Token。 ID 令牌过期;刷新令牌没有。当 ID 令牌过期时,我必须调用另一个端点,称为 令牌交换,以使用我的刷新令牌获取新的 ID 令牌。
1 There is a rumored Google Identity Toolkit C# library, but the first result returned by that search I found it by leads to a 404 error instead of documentation.
什么有效
在 Firebase guides and the underlying Identity Toolkit guides 之后,到目前为止,我已成功将令牌交换端点与来自 bash 的 cURL
命令连接:
curl 'https://securetoken.googleapis.com/v1/token?key=[MY FIREBASE API KEY]' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=refresh_token&refresh_token=[MY REFRESH TOKEN]'
当然,我将 [MY FIREBASE API KEY]
替换为我的 Firebase Web API 密钥,并将 [MY REFRESH TOKEN]
替换为从符号 in/sign 向上端点返回的刷新令牌。
然而,尽管我进行了多次尝试,但我无法在 C# 中复制此 cURL
命令!
我失败的尝试
1.
这是我的原始代码,但它不起作用。
public async Task<bool> ExchangeToken()
{
FormUrlEncodedContent body = new FormUrlEncodedContent(new Dictionary<string, string>() {
{"grant_type", "refresh_token" },
{"refresh_token", Uri.EscapeDataString(user.refreshToken) }
});
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, "https://securetoken.googleapis.com/v1/token?key=" + apiKey);
message.Content = body;
message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
HttpResponseMessage res = await client.SendAsync(message);
}
不幸的是,我收到此 401 (Unauthorized)
错误响应:
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
这很奇怪,考虑到我从应该是等效的 cURL
命令得到 2XX (OK)
响应...
2.
感谢 very nice website 我刚刚发现,我能够 "convert" 我的 cURL
命令进入 C# 代码。但是,这没有用。我得到了与尝试 #1 完全相同的错误。
public async Task<bool> ExchangeToken()
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://securetoken.googleapis.com/v1/token?key=[I WOULD INSERT MY KEY HERE]"))
{
request.Content = new StringContent("grant_type=refresh_token&refresh_token=[INSERT REFRESH TOKEN HERE]", Encoding.UTF8, "application/x-www-form-urlencoded");
var res = await client.SendAsync(request);
}
}
可能的线索
- 我对所有其他端点的所有其他请求都有效。有两个显着差异:1) API 在技术上不是 Firebase 的,而是 Google Identity Toolkit 的。 2) 这是我使用的唯一端点,它使用
application/x-www-form-urlencoded
的Content-Type
header 而不是application/json
。
我的问题/TL;DR
How do I interface with the Google Identity Toolkit API's Token Exchange endpoint using C#? (Though I'm currently using the HttpClient class, I'm totally open to other solutions! They just have to be compatible with Unity3D.)
提前致谢!
Google 希望您使用 Firebase 进行身份验证。虽然 Firebase 没有 Google 提供的 .NET 客户端 SDK,但有
如果您不使用 Firebase 并使用 oAuth/OpenID 自己连接端点来执行必要的任务,那也可以。有一个 Google .NET SDK 可以帮助您解决这个问题……一点点。 SDK 列出了 Google 个被 SDK "supported" 的 API; Google Cloud Identity v1
和 v1beta
API 都在列表中。因此,您可以通过此 .NET SDK 调用 Google Cloud Identity 端点。您确实必须了解各种身份验证流程的含义,而在 Firebase 中,作为应用程序开发人员,大部分机制都是从您那里抽象出来的。
在仔细研究了代码之后,我记得我在 HttpClient
上设置了默认授权:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", idToken);
这已包含在所有其他 API 调用中,因为它们需要使用 ID 令牌进行身份验证。但是,这似乎混淆了令牌交换端点;它必须 1) 寻找授权 header, 然后 2) 使用刷新消息内容中提供的令牌。
如何解决这个问题
- 不要在
HttpClient
上设置默认值 header(它应该被重用于 所有 的 HTTP 请求),而是执行以下操作:
var req = new HttpRequestMessage(/* HttpMethod enum value, endpoint URL/IP */);
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", user.idToken); //Set the authorization per-request, not globally
var res = await client.SendAsync(req);
- 然后只需调用令牌交换端点即可!
来自Firebase REST API Documentation:
You can refresh a Firebase ID token by issuing an HTTP POST request to the securetoken.googleapis.com endpoint.
https://securetoken.googleapis.com/v1/token?key=[API_KEY]
只需在 body 中提供一个 refresh_token
参数(以及值为 refresh_token
的强制性 grant_type
)。 请勿提供授权header。
希望这对遇到同样问题的人有所帮助!
作为替代方案,您还可以使用 https://github.com/google/apis-client-generator 从发现文档生成 c# 客户端。我在生成我的文件时遇到了一些命名冲突,但在解决这些冲突之后就可以了。