AWS Cognito 用户名/电子邮件登录名区分大小写

Posted

技术标签:

【中文标题】AWS Cognito 用户名/电子邮件登录名区分大小写【英文标题】:AWS Cognito username/email login is case-sensitive 【发布时间】:2018-06-28 18:35:03 【问题描述】:

设置

我正在使用 AWS Cognito 来管理我的 Web 应用程序的用户注册和用户访问。具体来说,我正在使用 Cognito 托管的 UI。这意味着 Cognito 为我的用户提供了一个注册用户界面,我无权修改我的应用程序的用户注册或登录页面(Cognito 提供的控件除外)。我使用电子邮件地址作为用户名,因此只需要求新用户提供电子邮件地址和密码。

问题

Cognito 将电子邮件地址视为区分大小写。如果用户使用电子邮件地址 JOHN_smith@randommail.com 注册,则他们无法使用 john_smith@randommail.com 登录。

我希望用于注册和登录的用户电子邮件地址不区分大小写。

我尝试过的

通常,通过在客户端将电子邮件地址设置为小写,然后再将其发送到服务器,这将很容易处理。但是我无法访问客户端 UI,因为它由 Cognito 托管。

因此,我的计划是尝试使用由Cognito pre-signup trigger 调用的 Lambda 函数来小写用户提供的电子邮件。

预注册

当用户尝试时,Amazon Cognito 会调用此触发器 注册(注册),允许您执行自定义验证以 接受或拒绝注册请求。

这是我写的 lamdba 函数:

'use strict';

console.log('Loading function');

exports.handler = (event, context, callback) => 
    console.log('Received event:', JSON.stringify(event, null, 2));

    var triggerSource = event.triggerSource;
    console.log('Received triggerSource:', triggerSource);

    var email = event.request.userAttributes.email;
    console.log('Received email:', email);

    var modifiedEvent = event;

    if (email !== null) 
        var lowerEmail = email.toLowerCase();
        modifiedEvent.request.userAttributes.email = lowerEmail;
        console.log('Set email in request to', lowerEmail);
        console.log('Modified event:', JSON.stringify(modifiedEvent, null, 2));
     else 
        console.log('Email evaluated as NULL, exiting with no action');
    

    // Return result to Cognito
    callback(null, modifiedEvent);
;

在事件请求中的电子邮件地址被修改为小写 (john_smith@randommail.com) 的意义上,这“有效”。但是,当我的 Lambda 函数收到此事件时,似乎已经在用户池中创建了该帐户。更改请求中的电子邮件地址无效 - 原始电子邮件地址 (JOHN_smith@randommail.com) 仍出现在我的用户池中。我怀疑事件中唯一有效的字段是响应字段。这是我修改后的事件的样子:


    "version": "1",
    "region": "us-east-1",
    "userPoolId": "us-east-1_xxxxxxx",
    "userName": "xxxxxx-xxxx-xxxx-xxxx-xxxxxxx",
    "callerContext": 
        "awsSdkVersion": "aws-sdk-java-console",
        "clientId": "xxxxxxxxxxxxxxxxxxxxxx"
    ,
    "triggerSource": "PreSignUp_SignUp",
    "request": 
        "userAttributes": 
            "email": "john_smith@randommail.com"
        ,
        "validationData": null
    ,
    "response": 
        "autoConfirmUser": false,
        "autoVerifyEmail": false,
        "autoVerifyPhone": false
    

我的问题

我正在寻找使我的用户注册和登录不区分大小写的想法或示例。这可能包括对我的 lambda 触发器方法的更改或完全其他的更改。

请注意,我知道我可以实现自己的 UI,我只会在万不得已的情况下这样做。

【问题讨论】:

文档说用户名区分大小写,但电子邮件不区分大小写。除了电子邮件之外,您是否反对使用用户名? 显然登录电子邮件应该不区分大小写,这是亚马逊方面的一个错误,您是否尝试过记录错误报告或支持请求? 我不同意。电子邮件不区分大小写,我已经看到人们因此可以访问他们不应该拥有的帐户。 显然目前无法使电子邮件不区分大小写。如果您决定实现自己的 UI,我目前正在客户端将其小写,并在 preSignUp tigger 中验证其是否小写。 这不是错误。根据RFC5321,电子邮件地址的本地部分 (local-part@domain) 区分大小写。这是因为从历史上看,本地部分是用户名,而用户名在某些操作系统上曾经并且仍然是区分大小写的。亚马逊只是遵循 RFC。但这并不意味着他们不应该提供不区分大小写的选项。 【参考方案1】:

修复了新用户池。您现在可以关闭区分大小写。

https://aws.amazon.com/about-aws/whats-new/2020/02/amazon-cognito-user-pools-service-now-supports-case-insensitivity-for-user-aliases/

【讨论】:

哇哦!尽管我自己的用户池现在永远停留在区分大小写的状态,但是。 这是一个迁移到新池的计划aws.amazon.com/blogs/security/… 不幸的是,这不适用于旧池。并且没有明确记录的方法来转换旧池。文档声称您可以使用 lambda 触发器进行迁移,但没有说明如何迁移。 您可以在此处找到将用户导入新池的文档:docs.aws.amazon.com/cognito/latest/developerguide/… 基本上有 3 个选项。 2 涉及一个 lambda,一个是 csv 方法。只有一个 lambda 选项不需要您的用户重置密码。【参考方案2】:

您可以在注册后触发 Lambda 函数将电子邮件更改为小写。无需实际测试,您应该可以trigger a Lambda post confirmation。该 Lambda 可以使用从您选择的 SDK 调用的AdminUpdateUserAttributes API 将电子邮件更改为小写。

请注意,用户名也区分大小写。

【讨论】:

这是一种有趣的方法,可能会有所帮助(因为该帐户将具有“正确”大小写)。但是,我认为基本问题仍然存在 - 即使您在确认后将电子邮件小写,在登录期间输入大写字母的用户仍将被拒绝身份验证。 对。而且您正在使用托管的 UI。那么,如何使用pre-authentication Lambda trigger 将 Cognito 中的电子邮件属性更改为用户输入的任何情况?因此,如果用户在网页上输入“MyEmail@host.com”,则检查 lower("MyEmail@host.com")==lower(email_in_cognito),然后将 Cognito 中的电子邮件属性设置为“MyEmail@” .然后,大小写应该与流程的其余部分匹配。可能是?再次,没有测试。感觉很蠢,我知道。 Or not。假设这仍然是真的。哦,好吧。【参考方案3】:

既然用户名区分大小写:为什么不直接使用用户名作为电子邮件地址,并让 prehook 使用用户名填充电子邮件字段?

【讨论】:

【参考方案4】:

创建帐户时将用户名设为小写。登录时将用户名设为小写。至少这样您只需重新创建具有大写字符的用户。或者您可以重建整个用户池并迁移用户,但谁知道这会对密码和 MFA 产生什么影响。现有用户池似乎不值得麻烦。希望您正在做一个全新的项目,并且您可以在创建用户池时选择不区分大小写的选项。

【讨论】:

【参考方案5】:

另一种可能性是,如果您可以创建一个用户注册 api,它将在 cognito 中创建用户。在修剪电子邮件并在电子邮件上执行小写之后。您可以在此之前执行您的自定义步骤。

您说得对,注册前触发器基本上是在执行注册后被调用的。

https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html#aws-lambda-triggers-pre-registration-tutorials

【讨论】:

这并不试图回答这个问题。我知道如何使用 cognito API 在我自己的页面上实现解决方案。

以上是关于AWS Cognito 用户名/电子邮件登录名区分大小写的主要内容,如果未能解决你的问题,请参考以下文章

AWS Cognito 登录 iOS (swift)

Aws cognito添加预定义用户

我可以以编程方式创建 AWS Cognito 用户登录吗?

AWS Cognito:处理相同用户(使用相同电子邮件地址)从不同身份提供商(Google、Facebook)登录的最佳实践

如何从通过 Google/Federated Login 登录的 AWS Cognito 检索 id 令牌

AWS Cognito 用户身份验证