我在我的应用程序中安装了OneLogin,并且运行良好。我正在使用MongoDB数据库存储会话、帐户和用户。现在,我从我的旧WordPress网站(它不使用OneLogin,而是本机WordPress登录)导入用户数据。
因此,基本上我从WordPress导入了用户数据,并使用email_id、name等填充了用户集合。当我使用OneLogin登录到我的应用程序时,它会抛出错误信息OAuthAccountNotLinked。当我研究,我可以看到,你是不推荐自动链接的用户帐户的安全原因。但在我的例子中,它是我的客户组织现在已经开始使用的OneLogin提供程序。而新的OneLogin用户注册是由管理员手动批准的。所以安全方面不会有问题。我们只使用OneLogin作为auth提供者!
如何在此场景中设置自动链接?因为我的MongoDB集合中有10,000多个用户(从旧的WordPress网站导入)。每个用户都被要求在OneLogin手动注册,使用他们以前在旧的WordPress网站上使用的电子邮件id,并在OneLogin中手动批准。
谢谢
发布于 2022-06-15 21:11:54
因为我找不到一个直接的解决方案,所以我想出了一个解决办法。这不是一个完美的解决方案,但是做好了这份工作。也许其他人会在这里发布更好的解决方案。
因此,我所做的是,将所有旧用户数据导入到我的users
数据库中的MongoDB集合中。NextAuth使用这个users
、accounts
和session
集合来存储用户和相关数据。顺便说一下,会话数据是存储在数据库中的。
在我的示例中,我们向现有用户发送了唯一的OneLogin注册URL(从OneLogin管理仪表板创建),以便他们在OneLogin中创建一个新帐户。然后,当用户在OneLogin注册一个帐户时,管理员批准/拒绝该用户。如果他们被批准,他们将有资格登录到我们的应用程序使用他们的OneLogin凭证。
我注意到的是,当用户尝试登录时,NextAuth会检查users
集合中的email
字段以找到匹配的记录。因为我们从WordPress数据库导入了用户,所以我们只在users
集合中有记录,而在accounts
集合中没有任何记录。在accounts
集合中,NextAuth存储access_token、user_id (映射到users
集合)、提供程序详细信息等。
因此,在登录期间,NextAuth进行内部检查,并在users
集合中找到现有的email
,但是它无法识别用户,因为没有关于提供者(OneLogin)的详细信息。
来自accounts
集合的记录:
因此,我所做的就是通过在users
字段的值中附加一个_TEMP
来更新email
集合中的所有记录。例如,如果有一个带有值abc@abc.com
的记录,它将成为abc@abc.com_TEMP
然后,我在我的/api/check_old_account
应用程序中编写了一个API路由( NextJS ),它做了以下工作:
users
集合中搜索末尾为"_TEMP“的同一个电子邮件id_TEMP
版本,则返回一个表示存在旧帐户的响应。然后,在主页中,如果用户登录,我编写了调用上述api (/api/check_old_account
)的代码。当加载所有内容时,在主页中只进行一次此调用。在这里,使用OneLogin登录没有错误,因为我们通过附加_TEMP
来重命名users
集合中的现有电子邮件id。因此,当用户登录时,users
集合也会向accounts
集合插入一个新记录和他们的电子邮件及相关数据。基本上,现在该用户在users
集合中有两条记录。一个是他们最初的电子邮件id记录,现在当登录(例如:abc@abc.com
)和他们的旧导入帐户(例如:abc@abc.com_TEMP
)时被插入。我之所以只编写在主页中调用API的代码,是因为在用户登录后,它们将被重定向到主页。因此,我认为没有必要在全局或其他地方编写代码。
因此,如果上面的API响应显示存在一个旧帐户,我会向用户显示一个警告弹出,表示数据库中存在一个旧帐户,并询问他们是否要链接该旧帐户。如果用户按下“是”按钮,我将调用/api/link_old_account
。在此API路由中,编写代码以执行以下操作:
_TEMP
集合中存在当前登录用户的email
版本,请查找在accounts
集合中有映射的相应的记录_id
。userId
版本电子邮件更改accounts
集合中相应记录(当前登录的用户id)的_TEMP
字段的值。_id
删除记录。email
字段中删除_TEMP
字段来更新它userId
集合的sessions
字段中。这样,这个用户当前登录的会话就会失效。res.redirect(307, '/')
将用户重定向回主页。到目前为止,解决方案似乎还不错。
发布于 2022-06-13 05:14:07
从原始站点中直接引用
自动登录链接在任意提供商之间是不安全的-除了允许用户通过电子邮件地址登录作为后备(因为他们必须验证他们的电子邮件地址作为流程的一部分)。 当一个电子邮件地址与一个OAuth帐户相关联时,并不一定意味着它已被验证为属于帐户持有人--如何处理电子邮件地址验证并不是OAuth规范的一部分,而且提供者之间也有差异(例如,有些不首先验证,有些确实首先验证,另一些则返回指示验证状态的元数据)。 使用自动登录链接,这可以被不良行为者利用,通过创建与另一个用户的电子邮件地址相关联的OAuth帐户来劫持帐户。 由于这个原因,在登录的任意提供者之间自动链接帐户并不安全,这就是为什么这个特性通常不是由身份验证服务提供的,也不是由NextAuth.js提供的。 在某些站点上可以看到自动帐户链接,有时是不安全的。从技术上讲,如果您信任所有涉及的提供商,以确保他们已经安全地验证了与该帐户相关的电子邮件地址,但需要将信任(和转移风险)交给这些提供商以安全地处理该过程,则可以在技术上安全地进行自动帐户链接。 在此安全的情况下,示例包括您控制的OAuth提供程序(例如,只授权组织内部的用户)或您明确信任的验证用户电子邮件地址的提供者。 自动帐户链接不是NextAuth.js的一个计划特性,但是在安全的方式下,可以改进帐户链接和处理这个流程的用户体验。通常情况下,这涉及到提供一个备用选项,通过电子邮件登录,这已经是可能的(并建议),但该流的当前实现可以改进。 提供对其他提供者的安全帐户链接和断开连接的支持--只有在用户已经登录时才能完成--最初是v1.x中的一个特性,但自v2.0以来就没有出现过,计划在以后的版本中返回。
您可能需要编写自己的实现来处理这种情况。并在每个提供者调用时调用该实现。就像检查一样,电子邮件已经存在于DB中,通过OTP等额外的验证。最后,当一切都过去时,让用户进入,并将一些额外的信息存储在DB中,以供将来参考。
https://stackoverflow.com/questions/71643948
复制相似问题