如何在 SUUNTO API OAuth2 的第二步避免 401 Unauthorized 响应?

How to avoid 401 Unauthorized response at the second step of the SUUNTO API OAuth2?

我想将 SUUNTO API 集成到 Flutter 应用程序中。我已注册到 SUUNTO API 区域,我有我的客户 ID、API 密钥和机密。我只是在开发者订阅中,因为我正在试水。我可以轻松获得授权代码(https://apizone.suunto.com/how-to-start 的第 4.4 步),但是当我尝试使用该代码获取 JWT 令牌(第 4.5 步)时,总是收到 401 Unauthorized。

他们的 FAQ https://apizone.suunto.com/faq 中实际上提到了这一点,但我已经按照我的客户端 ID 和密码建议使用了基本身份验证。

const REDIRECT_URL = "suuntoflutter://redirect/";

  Future<SuuntoToken> _getSuuntoToken(
    String clientId,
    String secret,
    String code,
  ) async {
    final encodedRedirectUrl = Uri.encodeQueryComponent(REDIRECT_URL);
    final params = "?grant_type=authorization_code&code=$code&redirect_uri=$encodedRedirectUrl";
    final tokenRequestUrl = "https://cloudapi-oauth.suunto.com/oauth/token" + params;
    final base64String = base64.encode(utf8.encode("$clientId:$secret"));
    final tokenResponse = await http.post(Uri.parse(tokenRequestUrl), headers: {"Authorization": "Basic: $base64String"});

我发这篇文章是因为我写信给 SUUNTO 但没有得到任何回复,我希望有人能在这里提供帮助。每个健身门户网站在 OAuth2 上都有一些变化,我现在可以完全使用 Strava 集成和 Under Armour 集成。

我对 SUUNTO 的尝试:

  1. grant_typecoderedirect_uri 参数编码为正文中的表单提交,而不是 URL 参数。一些 OAuth2 集成就是这样做的。这并没有改变任何东西。
  2. 我更改了客户端密码以确保我使用的是正确的密码。没有改变任何东西。
  3. 我尝试使用我的 API 区域凭据而不是 ClientID:ClientSecret 进行基本身份验证。这没有多大意义,但我仍然绝望地尝试,但它并没有改变任何东西。
  4. 我尝试使用我的 SUUNTO 最终用户凭证而不是 ClientID:ClientSecret 进行基本身份验证。这根本没有任何意义,但我仍然绝望地尝试,但它并没有改变任何东西。

我运行没主意了。

我回到开始,并能够使用 SUUNTO 文档示例 curl 命令 curl -v https://cloudapi-oauth.suunto.com/oauth/token --user <client id>:<client secret> -d grant_type=authorization_code -d redirect_uri=<redirect URI> -d code=<authorization code from step 4.4>.

获得 JWT 令牌

在那之后我又经历了很多变体(发送参数形式编码或 URL 等)直到我意识到它只是基本身份验证中的一个流氓额外字符 header 字符串插值:和额外的意外冒号:

"Basic $base64String" 对比 "Basic: $base64String"。那个额外的冒号就是问题所在。