【发布时间】:2019-12-18 15:55:56
【问题描述】:
一些背景资料
我正在使用 C# 在 Unity 中构建游戏。由于我使用的是 Firebase,而现成的 Unity Firebase SDK 在我的情况下无法工作1,因此我通过 C# 的 HttpClient 类(@987654329 附带)与 Firebase's REST API 进行交互@)。
我目前正在努力使用 Firebase 身份验证 API。对于那些不熟悉 OAuth API 的人,当我调用注册或登录端点时,我会同时获得一个 ID 令牌 和一个 刷新令牌。 ID 令牌过期;刷新令牌没有。当 ID 令牌过期时,我必须调用另一个端点,称为 Token Exchange,以使用我的刷新令牌获取新的 ID 令牌。
1 有传言称Google Identity Toolkit C# library,但我找到它的搜索返回的第一个结果导致 404 错误而不是文档。 ????
什么工作
按照Firebase guides 和底层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] 替换为从登录/注册端点返回的刷新令牌。
然而,尽管我做了很多尝试,我还是无法在 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,我能够将我的 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)这是我使用的唯一一个使用
Content-Type标头的application/x-www-form-urlencoded而不是application/json的端点。
我的问题/TL;DR
如何使用 C# 与 Google Identity Toolkit API 的 Token Exchange 端点交互? (虽然我目前正在使用 HttpClient 类,但我完全愿意接受其他解决方案!它们只需要与 Unity3D 兼容。)
提前致谢!
【问题讨论】:
标签: c# firebase http oauth google-identity-toolkit