JWT (JSON Web Token) in PHP ohne Verwendung einer Bibliothek von Drittanbietern. Wie unterschreibe ich?

Lesezeit: 4 Minuten

Es gibt einige Bibliotheken zum Implementieren von JSON Web Tokens (JWT) in PHP, wie z php-jwt. Ich schreibe meine eigene, sehr kleine und einfache Klasse, kann aber nicht herausfinden, warum meine Signatur die Validierung nicht besteht Hier obwohl ich versucht habe, mich an den Standard zu halten. Ich versuche es seit Stunden und ich stecke fest. Bitte helfen Sie!

Mein Code ist einfach

//build the headers
$headers = ['alg'=>'HS256','typ'=>'JWT'];
$headers_encoded = base64url_encode(json_encode($headers));

//build the payload
$payload = ['sub'=>'1234567890','name'=>'John Doe', 'admin'=>true];
$payload_encoded = base64url_encode(json_encode($payload));

//build the signature
$key = 'secret';
$signature = hash_hmac('SHA256',"$headers_encoded.$payload_encoded",$key);

//build and return the token
$token = "$headers_encoded.$payload_encoded.$signature";
echo $token;

Der base64url_encode Funktion:

function base64url_encode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

Meine Header und Payload stimmen perfekt mit der überein Validierungsseiten Standard-JWT, aber meine Signatur stimmt nicht überein, sodass mein Token als ungültig gekennzeichnet wird. Dieser Standard scheint wirklich einfach zu sein, also was ist falsch an meiner Signatur?

Benutzeravatar von BeetleJuice
KäferSaft

Ich habe es gelöst! Mir war nicht klar, dass die Signatur selbst base64-codiert sein muss. Außerdem musste ich den letzten optionalen Parameter der festlegen hash_hmac Funktion zu $raw_output=true (sehen die Dokumente. Kurz gesagt, ich musste meinen Code vom Original ändern:

//build the signature
$key = 'secret';
$signature = hash_hmac('sha256',"$headers_encoded.$payload_encoded",$key);

//build and return the token
$token = "$headers_encoded.$payload_encoded.$signature";

Zum Korrigierten:

//build the signature
$key = 'secret';
$signature = hash_hmac('sha256',"$headers_encoded.$payload_encoded",$key,true);
$signature_encoded = base64url_encode($signature);

//build and return the token
$token = "$headers_encoded.$payload_encoded.$signature_encoded";
echo $token;

  • Funktioniert dies über Netzwerke und verschiedene URLs …? Generieren dieses Tokens auf dem HTTP-Server und Verifizieren auf dem HTTPS-Server. es scheitert jedes mal..

    – MSQ

    13. Februar 2018 um 12:26 Uhr

Wenn Sie es mit lösen möchten RS256 (anstelle von HS256 wie OP) können Sie es so verwenden:

//build the headers
$headers = ['alg'=>'RS256','typ'=>'JWT'];
$headers_encoded = base64url_encode(json_encode($headers));

//build the payload
$payload = ['sub'=>'1234567890','name'=>'John Doe', 'admin'=>true];
$payload_encoded = base64url_encode(json_encode($payload));

//build the signature
$key = "-----BEGIN PRIVATE KEY----- ....";
openssl_sign("$headers_encoded.$payload_encoded", $signature, $key, 'sha256WithRSAEncryption'); 
$signature_encoded = base64url_encode($signature);

//build and return the token
$token = "$headers_encoded.$payload_encoded.$signature_encoded";
echo $token;

Ich habe viel länger gebraucht, als ich zugeben möchte

  • Mein Problem wurde mit “openssl_sign()” gelöst. Wenn ich versuche, mit hash_hmac zu signieren, kann der Schlüsselwert nicht richtig entschlüsselt werden. Aber jetzt mit base64url_encode & openssl_sign gelöst. Danke @Christian

    – Ganesh

    12. Januar 2022 um 15:21 Uhr

Benutzeravatar von gradus
Grad

https://github.com/gradus0/appleAuth
Look-Methode $appleAuthObj->get_jwt_token()

<?php
include_once "appleAuth.class.php";

// https://developer.apple.com/account/resources/identifiers/list/serviceId -- indificator value
$clientId = ""; // com.youdomen
// your developer account id -> https://developer.apple.com/account/#/membership/
$teamId = "";
// key value show in -> https://developer.apple.com/account/resources/authkeys/list
$key = ""; 
// your page url where this script
$redirect_uri = ""; // example: youdomen.com/appleAuth.class.php
// path your key file, download file this -> https://developer.apple.com/account/resources/authkeys/list
$keyPath=""; // example: ./AuthKey_key.p8 

try{    
    $appleAuthObj = new \appleAuth\sign($clientId,$teamId,$key,$redirect_uri,$keyPath); 
    
    if(isset($_REQUEST['code'])){
        $jwt_token = $appleAuthObj->get_jwt_token($_REQUEST['code']);
        $response = $appleAuthObj->get_response($_REQUEST['code'],$jwt_token);
        $result_token = $this->read_id_token($response['read_id_token']);

        var_dump($response);
        var_dump($result_token);
    }else{
        $state = bin2hex(random_bytes(5));
        echo "<a href="https://stackoverflow.com/questions/33773477/".$appleAuthObj->get_url($state)."">sign</a>";
    }
                                                                                    
} catch (\Exception $e) {
    echo "error: ".$e->getMessage();
}

  • Ihre Antwort könnte durch zusätzliche unterstützende Informationen verbessert werden. Bitte bearbeiten Sie, um weitere Details wie Zitate oder Dokumentation hinzuzufügen, damit andere bestätigen können, dass Ihre Antwort richtig ist. Weitere Informationen zum Verfassen guter Antworten finden Sie in der Hilfe.

    – Gemeinschaft
    bot

    2. Oktober 2021 um 8:07 Uhr

1444690cookie-checkJWT (JSON Web Token) in PHP ohne Verwendung einer Bibliothek von Drittanbietern. Wie unterschreibe ich?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy