Новый вход в Apple продолжает выдавать ошибку HTTP 400 Invalid_grant - PullRequest
2 голосов
/ 15 января 2020

Согласно Apple do c, чтобы проверить код авторизации для Apple, нам нужно POST к http://appleid.apple.com/auth/token с этими параметрами:

#!java

token = generateJWT(keyId, teamId, clientId, certificatePath);

HttpResponse<String> response = Unirest.post(authUrl)
     .header("Content-Type", "application/x-www-form-urlencoded")
     .field("client_id", clientId)
     .field("client_secret", token)
     .field("grant_type", "authorization_code")
     .field("code", authorizationCode)
     .asString();

где:

  • код_ авторизации : код авторизации, предоставленный клиентом приложения.

  • clientId : предоставляется Apple

  • токен : является секретом клиента. Генерация JWT с этим кодом:

#!java

private static String generateJWT(String keyId, String teamId, String clientId, String certificatePath) throws Exception {
        if (pKey == null) {
            pKey = getPrivateKey(certificatePath);
        }

        return Jwts.builder()
                .setHeaderParam(JwsHeader.KEY_ID, keyId)
                .setIssuer(teamId)
                .setAudience("https://appleid.apple.com")
                .setSubject(clientId)
                .setExpiration(new Date(System.currentTimeMillis() + (1000 * 60 * 5)))
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .signWith(pKey, SignatureAlgorithm.ES256)
                .compact();
    }

private static PrivateKey getPrivateKey(String certificatePath) throws Exception {
        //read your key
        try (PEMParser pemParser = new PEMParser(new FileReader(certificatePath))) {
            final JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
            final PrivateKeyInfo object = (PrivateKeyInfo) pemParser.readObject();
            final PrivateKey pKey = converter.getPrivateKey(object);
            return pKey;
        }
    }

Мы проверяем, что JWT содержит все поля, необходимые для яблока:

#!json

{
  "alg": "ES256",
  "typ": "JWT",
  "kid": "6876D87D6"
}
{
  "iat": 1578654031,
  "exp": 1578740431,
  "aud": "https://appleid.apple.com",
  "iss": "57675576576",
  "sub": "com.blahblah.client"
}

Но это проблема. Это всегда возвращает 400 HTTP Ошибка с этим телом:

#!json

{"error":"invalid_grant"}

Отсюда мы полностью потеряны. Мы не понимаем, почему код неправильный или почему он имеет ошибку invalid_grant.

1 Ответ

2 голосов
/ 23 января 2020

Мне удалось получить ошибку invalid_grant только при отправке запросов с неправильными значениями authorizationCode на https://appleid.apple.com/auth/token. Убедитесь, что вы получаете код так же, как в приведенном ниже примере кода swift.

Я думаю, что эта ошибка не относится к client_secret. Когда я изменяю client_secret с допустимого значения на пустую строку или какое-то неверное значение, я просто получаю ошибку invalid_client. И когда authorizationCode и client_secret неверны, я также получаю ошибку invalid_client.

Это то, что необходимо для запроса:

  1. app_id - это идентификатор пакета для приложения.
  2. client_secret - это токен jwt, который вы создаете, используя информацию, указанную в вопросе, и подписываете свой личный ключ, который вы также загружаете с developer.apple.com см. мой ответ здесь

  3. grant_type - это просто строка "authorization_code"

  4. код - это код авторизации, который вы получаете из приложения в формате строки , не формат данных
data = {
    'client_id': app_id,
    'client_secret': client_secret,
    'grant_type': grant_type,
    'code': authorizationCode,
}

headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
}

//python example request

response = requests.request(
    method='POST',
    url='https://appleid.apple.com/auth/token',
    data=data,
    headers=headers,
)

if response.status_code == 200:
    print("200")
else:
    print("error")
print(response.text)

Следующий код swift можно использовать для получения authorizationCode, identityToken и userIdentifier в правильном формате.

func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
    if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {

         let userIdentifier = appleIDCredential.user
         print("userIdentifier: \(userIdentifier)")

         let authorizationCode = String(data: appleIDCredential.authorizationCode!, encoding: .utf8)!
         print("authorizationCode: \(authorizationCode)")

         let identityToken = String(data: appleIDCredential.identityToken!, encoding: .utf8)!
         print("identityToken: \(identityToken)")

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...