问题
keys generated from: https://web-push-codelab.glitch.me/
response validated with: https://jwt.io/
Token being returned is valid! and yet I get the following error in chrome developer console: "invalid JWT provided"
Why isnt my code working?
CODE:
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
// Create token header as a JSON string
$header = json_encode(["alg" => "ES256","typ" => "JWT"]);
// Create token payload as a JSON string
$payload = json_encode(["aud" => "https://fcm.googleapis.com","exp" => time() + 3600,"sub" => "mailto:push@example.com"]);
// Encode Header to Base64Url String
$base64UrlHeader = base64url_encode($header);
// Encode Payload to Base64Url String
$base64UrlPayload = base64url_encode($payload);
// Create Signature Hash
$signature = hash_hmac("SHA256", $base64UrlHeader . "." . $base64UrlPayload, "PRIVATE_KEY", true);
// Encode Signature to Base64Url String
$base64UrlSignature = base64url_encode($signature);
// Create JWT
$token = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
$key = "PUBLIC_KEY";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send/.....');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = "Ttl: 60";
$headers[] = "Content-Length: 0";
$headers[] = "Authorization: vapid t=".$token.",k=".$key."";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
echo json_encode($result);
回答1:
In your code you use a private key to sign the token and a public key to verify, which can only be done for asymmetric signature algorithms, such as RS256
. But as signature algorithm you choose HS256
, which is a symmetric signature algorithm.
The alg
claim in the header determines, which algorithm is used to verify the signature. Therefore the algorithm name in the header must match with the algorithm used for signing.
For symmetric algorithms, you have to use the same secret for signing and verification. The secret is just a string in no special form, eg. 'my-super-secret' or better something like '12z4104cntc4ta9c53434c9032trcbwuer8r'.
Now you can either
- use one secret for
HS256
instead of the public and private keys. - change the algorithm to
RS256
, which would require some more code changes, because right now you calculate a HMAC-SHA256 (HS256
) hash.
I highly recommend to use a JWT library. There a list of libs for different languages and environments on https://jwt.io
来源:https://stackoverflow.com/questions/57963352/why-am-i-getting-php-invalid-jwt-provided-error