web-dev-qa-db-fra.com

Connectez-vous avec Apple = invalid_client

Je fais face à un très mauvais problème car j'ai lu tellement de guides et de tutoriels et rien ne fonctionne.

Le résultat est toujours le même: {"error":"invalid_client"}

J'obtiens le code, l'identitéToken et tout ce dont j'ai besoin - sauf l'appel à https://appleid.Apple.com/auth/token - à cause de invalid_client.

Voici mon URL pour obtenir le code.

https://appleid.Apple.com/auth/authorize?response_type=code&client_id=org.example.service&redirect_uri=https%3A%2F%2Fexample.org

Alors j'ai le workflow par défaut. Et après avoir accepté/ouvrir une session, je serai redirigé vers ma page.

https://example.org/?code=a277243e2ec324fb09ba1c3333a8e6576.0.abcde.u4xiTDP2qHXoNEaxrcrIGx

(Lorsque j'utilise l'API JavaScript, j'obtiens d'autres informations comme state, code et id_token. Je l'ai déjà essayé avec le "code" là aussi.)

Retour à la fonction principale.

Ceci est ma demande pour Apple.

'client_id' => 'org.example.service',  
'client_secret' => JWT-Data encoded (OPENSSL_ALGO_SHA256) see below  
'grant_type' => 'authorization_code',  
'code' => 'a277243e2ec324fb09ba1c3333a8e6576.0.abcde.u4xiTDP2qHXoNEaxrcrIGx'  

En-tête JWT:

{
  "alg": "ES256",
  "kid": "1ABC2345DE"
}  

Charge utile JWT:

{
  "iss": "1A234BCD56",
  "iat": 1571269964,
  "exp": 1571273564,
  "aud": "https://appleid.Apple.com",
  "sub": "org.example.service"
}

Réponse:

{  
  "error": "invalid_client"  
}  

Le message d'erreur inutile du monde.

Je ne sais pas pourquoi le client devrait être invalide.

J'ai une clé dans https://developer.Apple.com/account/resources/authkeys/list avec le nom de fichier téléchargé AuthKey_1ABC2345DE.p8. (signifie 1ABC2345DE est mon identifiant de clé)

J'ai ensuite une application iOS native avec l'identifiant "org.example" et un service avec l'identifiant "org.example.service".

Cela ne fonctionne pas avec les deux identifiants et mélangé différentes choses.

Rien. invalid_client.

Quelqu'un peut-il m'aider s'il-vous-plaît? Je suis assis ici pendant des heures et je ne reçois que invalid_client

Ma page de test:

<html>
<head>
</head>
<body>
<script type="text/javascript" src="https://appleid.cdn-Apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>
<div id="appleid-signin" data-color="black" data-border="true" data-type="sign in" data-width="330px" data-height="100px"></div>
<script type="text/javascript">
    AppleID.auth.init({
        clientId : 'org.example.service',
        scope : 'email',
        redirectURI: 'https://example.org',
        state : 'EN'
    });
</script>
</body>
</html>

Et PHP:

<?php
// index.php

// function by https://stackoverflow.com/q/56459075/1362858
function encode($data) {
    $encoded = strtr(base64_encode($data), '+/', '-_');
    return rtrim($encoded, '=');
}

// function by https://stackoverflow.com/q/56459075/1362858
function generateJWT($kid, $iss, $sub, $key) {
    $header = [
        'alg' => 'ES256',
        'kid' => $kid
    ];
    $body = [
        'iss' => $iss,
        'iat' => time(),
        'exp' => time() + 3600,
        'aud' => 'https://appleid.Apple.com',
        'sub' => $sub
    ];

    $privKey = openssl_pkey_get_private($key);
    if (!$privKey) return false;

    $payload = encode(json_encode($header)).'.'.encode(json_encode($body));
    $signature = '';
    $success = openssl_sign($payload, $signature, $privKey, OPENSSL_ALGO_SHA256);
    if (!$success) return false;

    return $payload.'.'.encode($signature);
}

$client_id = 'org.example.service';
$data = [
    'client_id' => $client_id,
    'client_secret' => generateJWT('1ABC2345DE', '1A234BCD56', $client_id, file_get_contents('AuthKey_1ABC2345DE.p8')),
    'code' => 'a277243e2ec324fb09ba1c3333a8e6576.0.abcde.u4xiTDP2qHXoNEaxrcrIGx',
    'grant_type' => 'authorization_code'
];
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://appleid.Apple.com/auth/token');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$serverOutput = curl_exec($ch);

curl_close ($ch);

/**
 * {"error":"invalid_client"}
 */
var_dump($serverOutput);

4
Patrick

Le problème était ce cryptage spécial. Dans ce blog, ils utilisent PHP pour tout sauf la génération client_secret. https://developer.okta.com/blog/2019/06/04/what-the-heck- is-sign-in-with-Apple

Et dans le texte, l'auteur explique cette phrase:

Some JWT libraries don’t support elliptic curve methods, so make sure yours does before you start trying this out.

Maintenant, cela fonctionne très bien avec exactement le code en haut - a seulement remplacé la génération client_secret.

1
Patrick