You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cognito自定义认证流调用respondToAuthChallenge报‘Invalid session for the user’错误排查求助

我帮你排查了下这个Invalid session for the user的问题,大概率是几个细节没处理对,咱们一步步来解决:

1. 移除AdminInitiateAuth中多余的CHALLENGE_NAME参数

当使用AuthFlowType.CUSTOM_AUTH发起初始认证请求时,不需要在authParams里添加CHALLENGE_NAME参数——这个参数是在响应挑战阶段才会用到的。多余的参数会干扰Cognito生成有效会话,导致后续响应挑战时session验证失败。

修改后的认证流程初始化代码:

try {
    AWSCognitoIdentityProvider client = getAWSCognitoIdentityClient();
    String username = "testuser";
    String password = "password1";
    final Map<String, String> authParams = new HashMap<String, String>();
    authParams.put("USERNAME", username);
    authParams.put("PASSWORD", password);
    // 移除多余的CHALLENGE_NAME参数
    final AdminInitiateAuthRequest initiateAuthRequest = new AdminInitiateAuthRequest()
            .withClientId("my client id")
            .withUserPoolId("my user pool")
            .withAuthFlow(AuthFlowType.CUSTOM_AUTH)
            .withAuthParameters(authParams);
    final AdminInitiateAuthResult result = client.adminInitiateAuth(initiateAuthRequest);
    String mfaCode = getUserInput();
    authenticateMFA(result, mfaCode);
} catch (Exception e) {
    e.printStackTrace();
}

2. 修正Create Challenge Lambda中challengeMetadata的使用

你现在把验证码直接存在了challengeMetadata里,这个字段是返回给客户端的公开元数据,不仅不安全,还可能导致Cognito的会话验证逻辑异常。正确的做法是只把验证码存在privateChallengeParameters(你已经做了这一步),challengeMetadata可以设置一个非敏感的标识,或者直接省略。

同时我帮你简化了重复的验证码生成逻辑:

const crypto = require("crypto");
var aws = require("aws-sdk");
var ses = new aws.SES({ region: "eu-west-2" });
exports.handler = async(event, context, callback) => {
    // 简化验证码生成逻辑
    var verificationCode = crypto.randomInt(0, 100000).toString().padStart(6, "0");
    console.log('send email');
    console.log('verificationCode: '+ verificationCode);
    console.log('email: '+ event.request.userAttributes.email);
    const params = {
        Destination: {
            ToAddresses: [event.request.userAttributes.email]
        },
        Message: {
            Body: {
                Html: {
                    Charset: 'UTF-8',
                    Data: `<html><body><p>This is your secret login code:</p> <h3>${verificationCode}</h3></body></html>`
                },
                Text: {
                    Charset: 'UTF-8',
                    Data: `Your secret login code: ${verificationCode}`
                }
            },
            Subject: {
                Charset: 'UTF-8',
                Data: 'Your secret login code'
            }
        },
        Source: 'my email'
    };
    await ses.sendEmail(params).promise().then((res) => {
        console.log(res);
    });
    // 仅保留私有参数存储验证码
    event.response.privateChallengeParameters = { "verificationCode": verificationCode };
    // 设置非敏感的元数据标识,或直接删除该行
    event.response.challengeMetadata = "EMAIL_MFA_CHALLENGE";
    return event;
};

3. 确保Session完整传递

虽然你已经传递了session,但要确认AdminInitiateAuthResult返回的session是完整的字符串(通常是Base64编码格式),没有被意外截断或修改。Java SDK返回的session默认是完整的,这一步主要是排查有没有额外的字符串处理逻辑破坏了session。

4. 增强Define Challenge Lambda的调试日志

在Define Challenge Lambda里添加日志输出,方便你在CloudWatch中查看会话状态,确认流程是否符合预期:

exports.handler = async(event, context, callback) => {
    // 添加调试日志
    console.log("Current session length:", event.request.session?.length);
    if (event.request.session?.length > 0) {
        console.log("Last challenge result:", event.request.session[event.request.session.length-1].challengeResult);
    }
    
    if (!event.request.session || event.request.session.length === 0) {
        event.response.issueTokens = false;
        event.response.failAuthentication = false;
        event.response.challengeName = 'CUSTOM_CHALLENGE';
    } else if (event.request.session.length === 1 && 
               event.request.session[0].challengeName === 'CUSTOM_CHALLENGE' && 
               event.request.session[0].challengeResult === true) {
        event.response.issueTokens = true;
        event.response.failAuthentication = false;
    } else {
        event.response.issueTokens = false;
        event.response.failAuthentication = false;
        event.response.challengeName = 'CUSTOM_CHALLENGE';
    }
    return event;
};

总结

最可能导致session无效的原因是初始认证请求中多余的CHALLENGE_NAME参数,先修改这一步应该就能解决问题。如果还有问题,可以通过CloudWatch查看Lambda的日志,确认会话流程是否按预期执行。

内容的提问来源于stack exchange,提问作者dynamo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:07:37