node.js - Meteor.loginWithPassword 不适用于带有 @ 字符的用户名

标签 node.js mongodb meteor

我在数据库中有一个具有以下凭据的用户:

{
    "_id": "zTHv8yqPSm3pmi4So",
    "emails": [{"address": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f0839f9d95959d91999cb09588919d809c95de939f9d" rel="noreferrer noopener nofollow">[email protected]</a>", "verified": true}],
    "services" : {
        "password" : {
            "bcrypt" : "$2b$10$L6HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo1IjZEx6.PBxfOeQHqS."
        },
        "resume" : {
            "loginTokens" : [ ]
        }
    },
    "username": "some@username",
    "profile": {
        "firstName": "Example",
        "lastName": "User",
    }
}

当我尝试使用用户名登录用户时,它说找不到用户:

Meteor.loginWithPassword("some@username", "123456", function(error) {
    console.log(error.reason); 
});

它适用于电子邮件,但不适用于用户名。

我希望能够灵活地使用电子邮件或用户名登录用户

最佳答案

API Meteor.loginWithPassword 实际上采用“选择器”作为第一个参数:

https://docs.meteor.com/api/accounts.html#Meteor-loginWithPassword

Meteor.loginWithPassword(selector, password, [callback])

ARGUMENTS

selector Object or String

Either a string interpreted as a username or an email; or an object with a single key: email, username or id.

在您的例子中,您使用字符串形式,并让 Meteor 尝试猜测它是用户名还是电子邮件。

但是由于您的用户名包含“@”字符,这会误导 Meteor 将其解释为电子邮件:

https://github.com/meteor/meteor/blob/release/METEOR%401.12.1/packages/accounts-password/password_client.js#L33-L38

Meteor.loginWithPassword = (selector, password, callback) => {
  if (typeof selector === 'string')
    if (!selector.includes('@'))
      selector = {username: selector};
    else
      selector = {email: selector};

这就是为什么当您尝试使用电子邮件时它工作正常,但由于用户名包含“@”而失败。

简单的解决方案是明确告诉 Meteor 您的目标是用户名(而不是电子邮件,尽管有“@”):

Meteor.loginWithPassword({
        username: "some@username"
    },
    "123456",
    function(error) {
        console.log(error.reason); 
    }
);

现在,如果我试图进一步猜测您的目标,您希望您的用户能够提供他们的电子邮件或用户名作为登录标识符,而无需明确告知它是什么? (就像一种“全能”登录 ID 输入)

在这种情况下,不幸的是,您必须自行检测它是电子邮件还是用户名。如果后者确实遵循“some@username”这样的模式,您可以尝试检测域是否不完整(无扩展名)。

但是,如果您的任何用户确实注册了一个看起来确实像电子邮件的用户名(例如“[email protected] ”),那么您可能无法区分他们。

更糟糕的是,某些用户可能选择的用户名与其他用户的电子邮件地址完全相同!那么,如何判断是哪一个正在尝试登录呢?

恕我直言,这对于稍微改善用户体验来说会变得很麻烦。要么阻止用户名包含“@”,即强制执行一条规则,使您能够区分差异,要么提供一种方法,让用户在不明确时明确判断它是电子邮件还是用户名(例如,可以通过某些 radio 来区分哪个)输入它;当登录 ID 明确时,它仍然可以包含“自动”模式)。

顺便说一句,我们还可以想象执行两步登录尝试:首先按原样,然后如果用户名包含“@”,则明确作为用户名,如上所述。但我们仍然可能陷入上述最坏的情况......

关于node.js - Meteor.loginWithPassword 不适用于带有 @ 字符的用户名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65598342/

相关文章:

meteor - 客户端订阅未从 Meteor 服务器发布接收数据

node.js - 在 node.js 中两次要求同一个文件有什么影响吗?

database - Mongoose 只更新不为空的字段?

mongodb - 如何在mongodb中存储数据

javascript - 关于更改 View 和将数组放入集合中的问题 Meteor

javascript - 在 Meteor 中控制用户访问

node.js - bcrypr 异步与同步 Node.js

javascript - Range header 是压缩字节还是未压缩字节的大小(以字节为单位)?

node.js - 在 Controller 中使用 api 请求 header 的有效方法,Node Express Js 中的模型

java - 当我在查询中使用 BigDecimal 时,我无法从 mongoDB 获取数据