Jak mogę dekodować google OAuth 2.0 JWT (OpenID Connect) w aplikacji node?
Mam tu kawał czasu, próbując użyć google OAuth do uwierzytelniania użytkowników w mojej aplikacji node express. Mogę z powodzeniem zrobić OAuth, który zwraca odpowiedź w ten sposób:
{
access_token: 'token string',
id_token: 'id.string',
expires_in: 3599,
token_type: "Bearer"
}
To wszystko ma sens, ale nie mogę na całe życie wymyślić, jak rozszyfrować JWT. Jestem trochę niedoświadczony w tym wszystkim, więc to wszystko jest dla mnie trochę obce.
Postępuj zgodnie z instrukcjami podanymi tutaj: https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken Próbuję dekodować JWT lokalnie w mojej aplikacji węzła.
Zainstalowałem https://github.com/hokaccha/node-jwt-simple w moim środowisku węzłów.
I jestem pewien, że muszę użyć tego certyfikatu ( https://www.googleapis.com/oauth2/v1/certs ) w tym wszystkim jakoś to rozszyfrować, ale jestem w trochę przegranej tutaj. Nie bardzo rozumiem, w jaki sposób mogę dostać certyfikat do mojej aplikacji node, a następnie jak go używać z node-JWT-simple. I nie bardzo zrozum, skąd wiem, kiedy muszę pobrać świeży certyfikat, a nie używać buforowanego.
Ktoś ma w tym jakieś doświadczenie, które może mi pomóc? Dzięki za pomoc. Jestem kompletnie zagubiony w tym momencie.** Update * *
Więc poczyniłem pewne postępy... Tak jakby. Dzwoniąc do jwt.decode (id_token, certificate, true); jestem w stanie pomyślnie zdekodować token. Nawet jeśli certyfikat var jest pustym obiektem {}. Pozostaje mi jeszcze 3 pytania. 1: Jaki jest najlepszy sposób, aby uzyskać certyfikat do aplikacji My express przy użyciu adresu URL od google? 2: Skąd będę wiedział, kiedy muszę pobrać jego świeżą wersję? 3: wydaje się, że Przejście W true dla noVerify (3rd arg w jwt.dekodowanie) to okropny pomysł. Jak mogę to uruchomić, nie przekazując tego? Wygląda na to, że jwt-simple spodziewa się hs256, a token używa rs256. Znowu, jestem w tym bardzo niedoświadczony, więc mogę być daleko od podstaw.* Aktualizacja * Dzięki pomocy Nat udało mi się to uruchomić! Myślę, że wypróbowałem każdy pojedynczy moduł JWT i JWS. To, na czym w końcu wylądowałem, jest następujące: Stwierdziłem, że żaden z modułów, na które patrzyłem, nie zrobił tego, czego chciałem po wyjęciu z pudełka. Stworzyłem następujące metody dekodowania JWT, których używam do dekodowania id_token, więc mogę pobrać dziecko z nagłówka.
module.exports = {
decodeJwt: function (token) {
var segments = token.split('.');
if (segments.length !== 3) {
throw new Error('Not enough or too many segments');
}
// All segment should be base64
var headerSeg = segments[0];
var payloadSeg = segments[1];
var signatureSeg = segments[2];
// base64 decode and parse JSON
var header = JSON.parse(base64urlDecode(headerSeg));
var payload = JSON.parse(base64urlDecode(payloadSeg));
return {
header: header,
payload: payload,
signature: signatureSeg
}
}
}
function base64urlDecode(str) {
return new Buffer(base64urlUnescape(str), 'base64').toString();
};
function base64urlUnescape(str) {
str += Array(5 - str.length % 4).join('=');
return str.replace(/\-/g, '+').replace(/_/g, '/');
}
Używam tego dekodowania, aby określić, czy muszę pobrać nowy publiczny cert z: https://www.googleapis.com/oauth2/v1/certs
Następnie używam tego publicznego cert i node-jws ( https://github.com/brianloveswords/node-jws ) jws.verify (id_token, cert) aby zweryfikować podpis!
Hura! Jeszcze raz dziękuję za dodatkowe wyjaśnienia podane w odpowiedzi. Pomogło mi to zrozumieć, co nawet próbowałem zrobić. Mam nadzieję, że to może pomóc innym.1 answers
Z punktu widzenia specyfikacji, to co napotkasz to [OpenID Connect].
Id_token jest podpisem [JWS] [JWT]. W tym przypadku jest to"."rozdzielony łańcuch z trzema składnikami. Pierwsza część to nagłówek. Drugi to ładunek. Trzeci to podpis. Każdy z nich jest zakodowanym łańcuchem Base64url.
Kiedy dekodujesz nagłówek, otrzymasz coś w stylu:
{"alg": "RS256", "kid": "43ebb53b0397e7aaf3087d6844e37d55c5fb1b67"}
The "alg" oznacza, że algorytm sygnatury to RS256, który jest zdefiniowany w [JWA]. "Kid" wskazuje identyfikator klucza publicznego odpowiadający kluczowi używanemu do podpisania.
Teraz jestem gotowy odpowiedzieć na niektóre z twoich pytań:
2: Skąd będę wiedział, kiedy będę musiał wyciągnąć nową wersję?
Jeśli potomek buforowanego pliku cert (pliku [JWK]) nie pasuje do potomka w nagłówku, pobierz nowy plik cert. (BTW, URL, z którego wyciągasz certy są nazywane x5u.)
3: wydaje się, że Przejście W true dla noVerify (3rd arg w jwt.decode) to okropny pomysł. Jak mogę to zrobić, nie przekazując tego w środku?
W rzeczy samej. Być może warto zajrzeć do innej biblioteki, takiej jak kjur.github.io/jsjws /
Referencje
- [OpenID Connect] openid.bitbucket.org/openid-connect-core-1_0.html
- [JWS] tools.ietf.org/html/draft-ietf-jose-json-web-signature
- [JWT] tools.ietf.org/html/draft-ietf-oauth-json-web-token
- [JWK] tools.ietf.org/html/draft-ietf-oauth-json-web-keys
- [JWA] tools.ietf.org/html/draft-ietf-jose-json-web-algorithms
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-28 19:38:25