Apple登录在网络上返回“ invalid_grant”,但应用程序未返回

时间:2020-06-11 14:00:31

标签: ios react-native oauth-2.0 apple-sign-in

我正在应用程序和Web上都应用Apple Signin。但是,如果我登录Web并进行验证,Apple服务器将始终返回错误invalid_grant

以下是我的服务的简单环境。

该应用是由ReactNative制作的,服务器是nodejs。

例如,证书值如下。

TeamID : 9BF12A
AppID : com.foo
ServiceID : com.foo.web (its bound primary key(?) is AppID com.foo)
KeyID : 12ABC4 (its bound primary key(?) is AppID com.foo)
...

在应用中登录后,它将authorizationCodeidentityToken发送到服务器网址/auth/apple

在网络上登录时,它会打开Apple登录页面。并且,在完成登录过程后,Apple会将codeid_token返回到服务器URL /auth/apple(引用here)。

因此,在我的服务器路由/auth/apple中,我从应用程序和网络收到code(authorizationCode)id_token(identityToken)

为了验证id_token,我制作了client_secret并使用以下函数验证code

// isrn : if the values(code and id_token) are come from the app(react native)
const get_client_secret = isrn => {
  // sign with RSA SHA256
  const privateKey = get_private_key(); // pseudo
  const token = jwt.sign({}, privateKey, {
    algorithm: 'ES256',
    expiresIn: '10h',
    audience: 'https://appleid.apple.com',
    issuer: 9BF12A, // TeamID
    subject: isrn ? com.foo : com.foo.web, // if the code from react native app, use AppID, else use ServiceID
    keyid: 12ABC4,
  });

  return token;
};


const verify = (code, isrn) => {
  let b;
  let e;

  return new Promise(resolve => {
    axios.post(
      'https://appleid.apple.com/auth/token',
      querystring.stringify({
        grant_type: 'authorization_code',
        code,
        client_secret: get_client_secret(isrn),
        client_id: isrn ? com.foo : com.foo.web,
        redirect_uri: 'https://testurl.com/auth/apple',
      }),
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
      })
    .then(r => {
      b = r.data;
    })
    .catch(err => {
      e = err.response ? err.response.data : { err };
    })
    .finally(() => {
      resolve({ b, e });
    });
  }).catch(err => {
    resolve({ b, e: err });
  });
};

我就像在路由/auth/apple中使用它

app.post('/auth/apple', (req, res, _) => {
  const { body: { isrn, code, id_token } } = req;

  verify(code, isrn).then(({ b, e }) => {

    // if code came from the app, b has result values like access_token and e is undefined
    // but if code came from the web, b is undefined and e has value 'invalid_grant'
    log('******* verify : ', b, e);

    // some process
  });
});

codeid_token来自网络时,错误将以invalid_grant返回,但对于app,返回值可以。

如何像应用程序一样验证来自网络的code

或者,我不能?

1 个答案:

答案 0 :(得分:0)

确保您使用的代码尚未过期。

授权响应中收到的授权码已发送至 您的应用。该代码仅供一次性使用,有效期为五分钟。

https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens