setup nodejs node library google auth node.js express google-oauth google-openid jwt

node.js - nodejs - oauth login google



¿Cómo puedo decodificar un google OAuth 2.0 JWT(OpenID Connect) en una aplicación de nodo? (1)

Desde el punto de vista de la especificación, lo que está encontrando es [OpenID Connect].

id_token es un [JWS] firmado [JWT]. En este caso, es un "." cuerda separada con tres componentes. La primera parte es el encabezado. El segundo es la carga útil. El tercero es la firma. Cada uno de ellos es una cadena codificada en Base64url.

Cuando decodifique el encabezado, obtendrá algo como:

{"alg": "RS256", "niño": "43ebb53b0397e7aaf3087d6844e37d55c5fb1b67"}

El "alg" indica que el algoritmo de firma es RS256, que se define en [JWA]. El "niño" indica la identificación de la clave pública que corresponde a la clave utilizada para firmar.

Ahora estoy listo para responder algunas de sus preguntas:

2: ¿Cómo sabré cuándo necesito obtener una nueva versión?

Cuando el elemento secundario del archivo cert en caché (un archivo [JWK]) no coincide con el elemento secundario del encabezado, busque un nuevo archivo cert. (Por cierto, la URL desde la que extrae los certs se llama x5u).

3: Parece que pasar en verdadero para noVerify (3er arg en jwt.decode) es una idea terrible. ¿Cómo puedo hacer que funcione sin pasar eso?

En efecto. Quizás desee consultar otra biblioteca, como kjur.github.io/jsjws/.

Referencias

  • [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

Me estoy divirtiendo mucho tratando de usar google OAuth para autenticar usuarios en mi aplicación de nodo expreso. Puedo hacer con éxito el OAuth, que devuelve una respuesta como esta:

{ access_token: ''token string'', id_token: ''id.string'', expires_in: 3599, token_type: "Bearer" }

Todo esto tiene sentido, pero no puedo imaginar cómo descifrar el JWT. Soy un poco inexperto en todo esto, así que esto es un poco extraño para mí.

Siguiendo las instrucciones enumeradas aquí: https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken Estoy intentando decodificar el JWT localmente en mi aplicación de nodo.

Instalé https://github.com/hokaccha/node-jwt-simple en el entorno de mi nodo.

Y estoy bastante seguro de que necesito usar este certificado ( https://www.googleapis.com/oauth2/v1/certs ) en todo esto de alguna manera para descifrarlo, pero estoy un poco perdido aquí. Realmente no entiendo cómo obtengo el certificado en mi aplicación de nodo, y luego cómo usarlo con node-jwt-simple. Y tampoco entiendo realmente cómo sé cuándo necesito sacar un certificado nuevo, versus usar uno en caché.

¿Hay alguien con experiencia en esto que pueda ayudarme?

Gracias por cualquier ayuda. Estoy totalmente perdido en este punto.

** Actualización **

Así que he avanzado un poco ... Un poco. Al llamar a jwt.decode (id_token, certificate, true); Soy capaz de decodificar exitosamente el token. Incluso si el certificado var es un objeto vacío {}. Esto me deja 3 preguntas todavía. 1: ¿Cuál es la mejor manera de obtener el certificado en mi aplicación express usando la URL de Google? 2: ¿Cómo sabré cuándo necesito obtener una nueva versión? 3: Parece que pasar en verdadero para noVerify (3er arg en jwt.decode) es una idea terrible. ¿Cómo puedo hacer que funcione sin pasar eso? Parece que jwt-simple está esperando hs256 y el token está usando rs256.

Una vez más, soy muy inexperto en esto, así que puedo estar fuera de la base aquí.

* ACTUALIZACIÓN * ¡ Gracias a la ayuda de Nat, pude hacer que esto funcionara! Creo que probé todos los módulos de nodo JWT y JWS por ahí. En lo que finalmente llegué fue de la siguiente manera: descubrí que ninguno de los módulos que examiné hizo lo que quería de inmediato. Creé los siguientes métodos de ayuda de decodificación jwt que estoy usando para decodificar el id_token, así que puedo obtener al niño del encabezado.

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, ''/''); }

Estoy usando esta decodificación para determinar si necesito obtener un nuevo certificado público de: https://www.googleapis.com/oauth2/v1/certs

¡Entonces estoy usando ese certificado público y node-jws ( https://github.com/brianloveswords/node-jws ) jws.verify (id_token, cert) para verificar la firma!

¡Hurra! Gracias de nuevo por la explicación adicional que brindó en su respuesta. Eso fue un largo camino para ayudarme a entender lo que estaba tratando de hacer. Espero que esto también ayude a otros.