【问题标题】:Cognito - Check validity of idTokenCognito - 检查 idToken 的有效性
【发布时间】:2020-09-07 15:59:16
【问题描述】:

我在 Node.js 中有一个后端 API,它从查询参数中检索 Amazon Cognito ID 令牌。我需要检查这个令牌是否有效。有没有办法通过使用aws-sdkamazon-cognito-identity-js SDK 来检查?

【问题讨论】:

  • 目前看来您只能使用不接受 id_tokens 的 /oauth2/userInfo 端点实时验证 access_tokens。 hrrrr

标签: node.js amazon-cognito


【解决方案1】:

我为此苦苦挣扎了几天,但我刚刚找到了解决方法,这是一个完整的功能,可以为您进行验证,您需要提供的只是 userPoolId 和与您之前创建的认知池相关的 pool_region然后你可以通过发送令牌作为参数来调用这个函数,如果令牌有效与否,你将在控制台上得到结果,这里是如何实现它:

  1. 创建一个名为 tokenValidation.js 的文件(例如)
  2. 将此代码粘贴到其中:

// 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
  1. 在你需要的时候像这样导入它:const validateToken = require('./tokenValidation')

  2. 最后这样称呼它:validateToken.ValidateToken(result.getAccessToken().getJwtToken())

我知道这是一个老问题,但我真的希望这对未来的其他人有所帮助。

【讨论】:

  • 这只会检查它是否具有有效的格式和正确的签名,以及它是否未过期。但它不会检查用户自发行此令牌以来是否已撤销其权限。
【解决方案2】:

我使用 AWS 库 https://github.com/awslabs/aws-support-tools/tree/master/Cognito/decode-verify-jwt 在带有节点的 lambda 中进行检查。

默认情况下它会检查 AccessToken,但您可以修改它以验证 IdToken。

替换:

if (claim.token_use !== 'access') {
  throw new Error('claim use is not access');
}

通过

if (claim.token_use !== "id") {
  throw new Error("claim use is not id");
}

console.log(`claim confirmed for ${claim.username}`);
result = {userName: claim.username, clientId: claim.client_id, isValid: true};

通过

console.log(`claim confirmed for ${claim["cognito:username"]}`);
result = {userName: claim["cognito:username"], clientId: claim.aud, isValid: true};

您甚至可以在结果中添加更多自定义属性。

【讨论】:

    【解决方案3】:

    Cognito 的 ID 令牌在解码时包含一个“exp”声明,它指示 ID 令牌在多长时间后无效。 引用OpenID官方documentation

    不得接受 ID 令牌的过期时间或之后 用于处理。该参数的处理要求 当前日期/时间必须早于所列的到期日期/时间 价值。

    要在 JavaScript 中解码 JWT 令牌,您可以参考 Auth0 提供的类似 JsonWebToken 的库。

    要使用该库使用上述库解码现有 ID Token,您可以参考以下代码 sn-p:

    // 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) 
    

    请注意,Cognito 生成的 JWT 令牌符合 OIDC,您也可以参考此documentation 了解有关 Cognito 令牌的更多信息。

    【讨论】:

    • 在验证令牌时不要忽略签名,否则攻击者创建假令牌是微不足道的
    【解决方案4】:

    亚马逊有一个库来解码和验证 Cognito 令牌:https://github.com/awslabs/aws-support-tools/tree/master/Cognito/decode-verify-jwt

    【讨论】:

      【解决方案5】:

      您可以通过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 });
      });
      

      【讨论】:

        猜你喜欢
        • 2020-07-13
        • 2019-09-01
        • 1970-01-01
        • 2011-04-17
        • 1970-01-01
        • 2018-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多