J'ai une API principale dans Node.js qui récupère un jeton d'ID Amazon Cognito à partir d'un paramètre de requête. J'aurais besoin de vérifier si ce jeton est valide. Existe-t-il un moyen de vérifier cela en utilisant le SDK aws-sdk
ou amazon-cognito-identity-js
?
5 Réponses :
Le jeton d'identification de Cognito contient une réclamation «exp» lors du décodage, qui indique le temps après lequel un jeton d'identification ne serait pas valide. Citant la documentation ,
Heure d'expiration à partir de laquelle le jeton d'identification NE DOIT PAS être accepté pour traitement. Le traitement de ce paramètre nécessite que le la date / heure actuelle DOIT être antérieure à la date / heure d'expiration indiquée dans la valeur.
Pour décoder le jeton JWT en JavaScript, vous pouvez vous référer à une bibliothèque comme JsonWebToken , fourni par Auth0.
Pour utiliser la bibliothèque pour décoder un jeton d'identification existant à l'aide de la bibliothèque mentionnée, vous pouvez vous référer à l'extrait de code suivant:
// get the decoded payload ignoring signature, no secretOrPrivateKey needed var decoded = jwt.decode(token); // get the decoded payload and header var decoded = jwt.decode(token, {complete: true}); console.log(decoded.header); console.log(decoded.payload)
Veuillez noter que le Les jetons JWT générés par Cognito sont compatibles OIDC, et vous pouvez également vous référer à ceci documentation pour plus d'informations sur les jetons de Cognito.
Vous ne voulez pas ignorer la signature lors de la vérification des jetons, sinon il est trivial pour les attaquants de créer de faux jetons
Amazon dispose d'une bibliothèque pour décoder et vérifier les jetons Cognito: https://github.com/awslabs/aws-support-tools/tree/master/Cognito/decode-verify-jwt
Je fais l'enregistrement dans un lambda avec nœud à l'aide de la bibliothèque AWS https://github.com/awslabs/aws-support-tools/tree/master/Cognito/decode-verify-jwt .
Par défaut, il vérifie AccessToken mais vous pouvez modifier pour valider IdToken.
remplacer:
console.log(`claim confirmed for ${claim["cognito:username"]}`); result = {userName: claim["cognito:username"], clientId: claim.aud, isValid: true};
par
console.log(`claim confirmed for ${claim.username}`); result = {userName: claim.username, clientId: claim.client_id, isValid: true};
et
if (claim.token_use !== "id") { throw new Error("claim use is not id"); }
by
if (claim.token_use !== 'access') { throw new Error('claim use is not access'); }
Vous pouvez même ajouter plus d'attributs personnalisés dans le résultat.
J'ai eu du mal avec cela pendant quelques jours et je viens de trouver comment faire cela, voici une fonction entièrement fonctionnelle qui effectue la validation pour vous tout ce que vous devez fournir est le userPoolId et le pool_region liés au pool de cognito que vous avez précédemment créé puis vous pouvez appeler cette fonction où vous voulez en envoyant le jeton en tant que paramètre et vous obtiendrez votre résultat sur la console si le jeton est valide ou non, voici comment l'implémenter:
// Cognito data const userPoolId = "###########"; // Cognito user pool id here const pool_region = '#########'; // Region where your cognito user pool is created const jwt = require('jsonwebtoken'); const jwkToPem = require('jwk-to-pem'); const request = require('request'); // Token verification function const ValidateToken = (token) => { console.log('Validating the token...') request({ url: `https://cognito-idp.${pool_region}.amazonaws.com/${userPoolId}/.well-known/jwks.json`, json: true }, (error, response, body) => { console.log('validation token..') if (!error && response.statusCode === 200) { pems = {}; var keys = body['keys']; for(var i = 0; i < keys.length; i++) { //Convert each key to PEM var key_id = keys[i].kid; var modulus = keys[i].n; var exponent = keys[i].e; var key_type = keys[i].kty; var jwk = { kty: key_type, n: modulus, e: exponent}; var pem = jwkToPem(jwk); pems[key_id] = pem; } //validate the token var decodedJwt = jwt.decode(token, {complete: true}); if (!decodedJwt) { console.log("Not a valid JWT token"); return; } var kid = decodedJwt.header.kid; var pem = pems[kid]; if (!pem) { console.log('Invalid token'); return; } jwt.verify(token, pem, function(err, payload) { if(err) { console.log("Invalid Token."); } else { console.log("Valid Token."); console.log(payload); } }); } else { console.log(error) console.log("Error! Unable to download JWKs"); } }); } // Exporting it to call it anywere you want exports.ValidateToken = ValidateToken
importez-le chaque fois que vous en avez besoin comme ceci: const validateToken = require ('./ tokenValidation')
et enfin appelez-le comme ceci: validateToken.ValidateToken(result.getAccessToken().getJwtToken())
Je sais que c'est une vieille question, mais j'espère vraiment que cela aidera les autres à l'avenir.
cela vérifie uniquement s'il est de format valide et signé correctement, et s'il n'a pas expiré. mais il ne vérifie pas si l'utilisateur a vu ses privilèges révoqués depuis l'émission de ce jeton.
Vous pouvez simplement vérifier avec aws-sdk CognitoIdentityServiceProvider
var params = { AccessToken: 'STRING_VALUE' /* required */ }; cognitoidentityserviceprovider.getUser(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response }); });
Il semble que vous ne puissiez jusqu'à présent valider les
access_token
qu'en temps réel à l'aide du point de terminaison/ oauth2 / userInfo
, qui n'accepte pas les id_tokens. hrrrr