Sign_in_with_apple:AuthorizationErrorCode.invalidResponse:未设置代码查询参数

Plu*_*Dev 5 authentication dart flutter apple-sign-in apple-authentication

我使用最新版本的sign_in_with_apple,并使用以下代码来允许通过Apple登录我在Android上的Flutter应用程序。

final credential = await SignInWithApple.getAppleIDCredential(
  scopes: [
    AppleIDAuthorizationScopes.email,
    AppleIDAuthorizationScopes.fullName,
  ],
  webAuthenticationOptions: WebAuthenticationOptions(
    clientId: '***Service Identifier***',
    redirectUri:
        // For web your redirect URI needs to be the host of the "current page",
        // while for Android you will be using the API server that redirects back into your app via a deep link
        kIsWeb ? Uri.parse('https://${window.location.host}/') : Uri.parse('https://***Backend***/callback'),
  ),
  nonce: nonce,
);
Run Code Online (Sandbox Code Playgroud)

我从README.md包中获取了后端代码:

apple_router.post("/callback", (request, response) => {
    console.log(">>> Apple callback received <<<");
    console.log("Body:");
    console.log(request.body);
    console.log("Query:");
    console.log(request.query);
    console.log("Params:");
    console.log(request.params);
    const redirect = `intent://callback?${new URLSearchParams(
        request.body
    ).toString()}#Intent;package=${process.env.ANDROID_PACKAGE_IDENTIFIER
        };scheme=signinwithapple;end`;

    console.log(`Redirecting to ${redirect}`);

    response.redirect(307, redirect);
});
Run Code Online (Sandbox Code Playgroud)

我还使用正确的域配置了 Apple 的所有内容,但在我的后端,当我登录应用程序时,仅收到一个空请求:

>>> Apple callback received <<<
Body:
{}
Query:
{}
Params:
{}
Redirecting to intent://callback?#Intent;package=***Android package ID***;scheme=signinwithapple;end
Run Code Online (Sandbox Code Playgroud)

这就是它在应用程序中无法正常工作的原因:

E/flutter (27962): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: SignInWithAppleAuthorizationError(AuthorizationErrorCode.invalidResponse, parseAuthorizationCredentialAppleIDFromDeeplink: No `code` query parameter set))
Run Code Online (Sandbox Code Playgroud)

我已经检查了所有内容好几次了,我不再知道这个问题可能来自哪里。有人有什么想法吗?

Zak*_*ain 0

使用此sign_in_with_apple,苹果将仅在首次授权时向您提供电子邮件、全名等信息。

因此,您必须采取几个步骤才能获得苹果授权。

Flutter/客户端代码/机制

void loginSignUpWithApple() async {
    SignInWithApple.getAppleIDCredential(
      scopes: [
        AppleIDAuthorizationScopes.email,
        AppleIDAuthorizationScopes.fullName
      ],
    ).then((value) {
      _socialLoginSignUp(value.authorizationCode, describeEnum(LoginMethod.APPLE));
    }).catchError((e) {
      showMessage("Something went wrong: $e", isError: true);
    });
  }
Run Code Online (Sandbox Code Playgroud)

后端代码/机制

  1. 使用Apple密钥id和私钥生成JWT
  2. 使用生成的 jwt 和 clint 发送的授权代码从苹果服务器获取身份验证令牌,然后从身份验证令牌响应中提取 IdToken
  3. 解码IdToken并获取IdTokenHeader
  4. 从 IdTokenHeader 获取 kId
  5. 使用 kId 从苹果服务器获取密钥列表,然后提取实际密钥
  6. 使用实际密钥创建苹果密钥到公钥
  7. 使用公钥和 IdToken 获取声明,然后解码声明以获取用户电子邮件
  8. 获取用户电子邮件后,您可以将此电子邮件存储在您的数据库或其他位置,并且您可以相信该邮件是有效的苹果邮件。

你可以看到后端实现代码,这是我们之前在java(spring boot)中实现的。

苹果登录的示例后端代码(如果链接不起作用,请尝试使用 VPN)