2016-04-28 9 views
4

ich zu Google API durch OAuth durch JWT zu verbinden versuchte zu verbinden versucht, aber ich erhalte diesen Fehler:ungültig JWT, wenn Google OAuth für Google-API

{ "error": "invalid_grant", "error_description": "Invalid JWT: Token must be a short-lived token and in a reasonable timeframe" }

In meinem JWT Calim stelle ich die iat um die aktuelle Zeit minus 1970-01-01 in Sekunden und exp bis iat + 3600 zu sein, weiß ich nicht, warum ich diesen Fehler immer noch bekomme. Wenn jemand die Antwort kennt, bitte meeeeee!

+1

Sind Sie eigenen JWT Anspruch zu machen? Zeit muss die aktuelle Zeit sein NTP https://en.wikipedia.org/wiki/Network_Time_Protocol – DaImTo

+0

danke für die Antwort, ich habe die Zeit auf UTC und jetzt bekomme ich einen ungültigen Signaturfehler, würden Sie wissen, was ich bin falsch machen? – andy

+0

$ sig = hash_hmac ('sha256', utf8_encode ($ base64encodedHeaderAndPayload), "----- BEGIN PRIVATSCHLÜSSEL ----- \ n privater Schlüssel \ n ----- END PRIVATE KEY ----- \ n "); $ signature = base64url_encode ($ sig); – andy

Antwort

1

Nicht sicher, ob Sie überhaupt zum Laufen bekommen, aber die folgenden einfachen Schritten arbeitete für mich, die PHP-Funktion openssl_sign():

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

//Google's Documentation of Creating a JWT: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests 

//{Base64url encoded JSON header} 
$jwtHeader = base64url_encode(json_encode(array(
    "alg" => "RS256", 
    "typ" => "JWT" 
))); 
//{Base64url encoded JSON claim set} 
$now = time(); 
$jwtClaim = base64url_encode(json_encode(array(
    "iss" => "[email protected]account.com", 
    "scope" => "https://www.googleapis.com/auth/prediction", 
    "aud" => "https://www.googleapis.com/oauth2/v4/token", 
    "exp" => $now + 3600, 
    "iat" => $now 
))); 
//The base string for the signature: {Base64url encoded JSON header}.{Base64url encoded JSON claim set} 
openssl_sign(
    $jwtHeader.".".$jwtClaim, 
    $jwtSig, 
    $your_private_key_from_google_api_console, 
    "sha256WithRSAEncryption" 
); 
$jwtSign = base64url_encode($jwtSig); 

//{Base64url encoded JSON header}.{Base64url encoded JSON claim set}.{Base64url encoded signature} 
$jwtAssertion = $jwtHeader.".".$jwtClaim.".".$jwtSig; 
+1

Entschuldigung, ich habe vergessen, dies zu aktualisieren. Das war in der Tat die richtige Antwort! Obwohl ich dies nicht mehr verwenden muss, da ich mit App Engine jetzt direkt auf Cloud Storage zugreifen kann. Aber trotzdem danke für die richtige Antwort! :) – andy

+0

Hey @Joseph Shih Ich habe ähnliches Problem, mein Fehler ist 'Invalid JWT Signature'. Können Sie Ihre POST-Anfrage teilen? Ich vermute, ich habe Probleme mit 'grant_type' im Anfragetext. – Michel

+0

@Michel, ein ungültiger JWT-Signaturfehler bedeutet, dass Ihre Signatur Ihren $ jwtHeader und $ jwtClaim nicht authentifizieren konnte. Verwenden Sie die richtige ISS (E-Mail-Adresse des Dienstkontos) und verwenden Sie den privaten Schlüssel aus Ihrer API-Konsole. Denken Sie auch daran, dass Sie die Signatur für Base-64 kodieren müssen (wie im obigen Beispiel). –

0

Wenn Sie die Schritte unter HTTP/Rest hier ausführen: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#formingheader, werden Sie sehen, dass Ihre Dienstkonten RSA SHA-256 unterstützen, und Sie scheinen HMAC zu verwenden.

+0

Also habe ich den folgenden Code geändert: ' $ sig = Hash (' SHA256 ', $ HeaderAndPayload, $ Geheimnis); $ Signatur = base64url_encode ($ sig); $ jwt = $ headerAndPayload. "." . $ Unterschrift; ' Ich bekomme aus irgendeinem Grund eine Signatur ungültig. $ secret ist der private Schlüssel, den ich von der Dienstkonto-Schlüssel-json-Datei erhalten habe. Würdest du wissen, was los ist? – andy

+0

Ich habe gerade herausgefunden, dass die Verwendung von Hash in PHP keinen geheimen Schlüssel verwendet, also sollte ich wahrscheinlich immer noch hash_hmac verwenden, und ich bekomme kein Ergebnis:/ – andy

+0

Es scheint Signierbibliotheken zu geben, die spezifikationskonforme JWTs erstellen. Zum Beispiel: https://github.com/namshi/jose – user2705223

1

Sie haben eine richtige Ablaufzeit für das Token setzen, wenn Sie das sehen Error. Beispiel:

var currentTime = new Date().getTime()/1000; //must be in seconds 
var exp = currentTime + 60; 

var auth_claimset = { 
     iss  : "...", 
     scope  : "...", 
     aud  : "...", 
     exp  : exp, 
     iat  : currentTime 
}; 
0

ich das gleiche Problem hatte, löste ich es durch die Synchronisierung meiner VMs Zeit, um die richtigen mit einem öffentlichen ntpserver hat:

ntpdate ntp.ubuntu.com