Мы начали внедрять вход с помощью Apple в наше мобильное приложение, но не можем успешно вызвать конечную точку токена (https://appleid.apple.com/auth/token). Мы получаем ответ 400 с телом [{"error": "invalid_client"}]. Я прочитал и перечитал детали о том, как генерировать секрет клиента. Мы используем java бэкэнд и, в частности, библиотеку nimbus для создания подписанного JWT.
final JWSHeader clientSecretHeader =
new JWSHeader.Builder(JWSAlgorithm.ES256)
.keyID("7N5XJ*****")
.build();
final Date issuedAtTime = Date.from(Instant.now());
final Date expirationTime = Date.from(Instant.now().plusSeconds(3600));
final JWTClaimsSet clientSecretClaims =
new JWTClaimsSet.Builder()
.issuer("HL46P*****")
.issueTime(issuedAtTime)
.expirationTime(expirationTime)
.audience("https://appleid.apple.com")
.subject("com.company.app")
.build();
final byte[] keyBytes = ...private key loaded from p8 file...;
final KeyFactory keyFactory = KeyFactory.getInstance("EC");
final ECPrivateKey privateKey =
(ECPrivateKey)keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
final JWSSigner jwtSigner = new ECDSASigner(signingKey);
final SignedJWT clientSecretJwt = new SignedJWT(clientSecretHeader, clientSecretClaims);
clientSecretJwt.sign(jwtSigner);
final MultiValueMap<string, string=""> map= new LinkedMultiValueMap<>();
map.add("grant_type", "authorization_code");
map.add("client_id", "HL46P*****");
map.add("client_secret", clientSecretJwt.serialize());
map.add("code", "code receiged from app...");
/* if User-Agent is not set, request fails with 400 invalid_client */
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set(HttpHeaders.USER_AGENT, "My App");
final HttpEntity<multivaluemap<string, string="">> request = new HttpEntity<>(map, headers);
final RestTemplate restTemplate = new RestTemplateBuilder().build();
final ResponseEntity response = response = restTemplate.postForEntity(
"https://appleid.apple.com/auth/token",
request,
GetTokenResponse.class
);
Полученный JWT выглядит следующим образом:
Заголовок
{
"kid": "7N5XJ*****",
"alg": "ES256"
}
Заявления
{
"aud": "https://appleid.apple.com",
"sub": "com.company.app",
"iss": "HL46P.....",
"exp": 1585583898,
"iat": 1585580298
}
В итоге мы определили, что если заголовок User-Agent не задан, API Apple не будет работать с кодом ответа 400 и invalid_client в качестве ошибки. Эта ошибка полностью вводит в заблуждение, но установка заголовка User-Agent разрешает ее.