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:处理相同用户(使用相同电子邮件地址)从不同身份提供商(Google、Facebook)登录的最佳实践