我目前遇到一个问题,用户注册时使用的电子邮件地址与他们签出时使用的电子邮件地址不同(他们的数据通过电子邮件地址存储在我们的后端)。但是,我不想在结帐之外阻止注册,因为(截至目前)我还允许在购买产品之前进行注册。我可以在结账时自动为用户生成一个帐户,但如果他们稍后使用另一封电子邮件注册,这不会改变任何事情。
我目前的想法是,我将添加一些方法来尝试确保他们在结帐时使用电子邮件进行注册。为此,我刚刚添加了一项功能,可以在结账时将他们的电子邮件保存在 localStorage 中,并在组合的登录/注册页面上自动填充。但显然,只有当他们使用相同的设备时,这才会有帮助。 我的另一个想法是,我会在每封电子邮件中包含一个令牌,作为我们门户的传出链接的参数,这也会在登录/注册其他设备时自动填充他们的电子邮件。
我的主要问题是上面的斜体句子是否是不好的安全实践。我确实使用NextJS(以及React),所以其中一些是在服务器端呈现的,但我想我必须处理该查询参数在客户端(?),在这种情况下,我可能必须创建一个未经身份验证的端点来将令牌转换为电子邮件。因此,任何拦截 URL 的人(有足够的动机)也可以找出我客户的电子邮件。这是一个合理的风险吗?我是否有不必要的偏执?如果没有,有什么替代方法可以实现我所描述的预期结果?我对想法持开放态度。
还欢迎对上述在 localStorage 中保存纯文本客户电子邮件的做法提出评论。
其他上下文:我使用 Firebase 进行身份验证,所有内容都是用 Typescript 编写的。
首先,如果有任何事情触及客户,请将其视为受到损害,直到证明并非如此。您永远不能依赖客户端代码。如果这样做,您必须重新验证服务器端。
让我们从链接中的纯文本电子邮件开始。基本上有两个风险:
但风险是影响和可能性的一个因素。在互联网规模上,即使对于低价值资产,您也可以将可能性视为“几乎确定”。
这些事件发生的影响将指导您采取控制措施来防止其发生。如果这只是显示问题,您可能不需要执行任何操作。说“欢迎(错误的电子邮件)”可能不值得修复。
但是如果您依赖此值进行某种形式的身份验证,那么您必须确保:
您可能还需要考虑这些要求:
这可能是一个完整的项目,但用“令牌”替换电子邮件就可以了:
generated_timestamp+email
这样的字符串,也许还有一些上下文,比如账号之类的。例如[email protected]_123456
。以分钟或小时为单位的时间戳就足够了。当服务器(记住,客户端不可信)收到令牌时,它将:
有关密钥管理的一些注意事项:
current
密钥解密,如果失败,请尝试使用 previous
密钥(如果有)。如果再次失败,请拒绝current
、future
和 previous
密钥的方案将简化部署future
密钥进行解密,并将其用作现在是 current
密钥的信号previous
密钥变成 future
后)删除 current
密钥,因为无论如何你都会拒绝这些令牌。