更改ASP.NET Core中的电子邮件工作流程

时间:2019-05-14 18:02:26

标签: asp.net-core asp.net-identity asp.net-core-2.2

如果用户想要更改为新的电子邮件地址,我使用:

var token = await _userManager.GenerateChangeEmailTokenAsync(user, newEmail);

...并发送包含此更改令牌的确认邮件。用户单击电子邮件中的链接,回到站点,现在我需要更改电子邮件。

但是,我不知道新的电子邮件地址。

我已经经历了确认邮件循环的麻烦,所以我想使用它。再次要求发送电子邮件可能会造成大错特错,这可能会使用户无法进入自己的帐户,这也是该用户的另一个障碍,还有更多代码需要我维护。

显而易见的解决方案:

  • 再问一次(冒犯错误的风险,并使邮件循环毫无意义)
  • 将新的电子邮件地址存储在User.NewEmailTemp中(是的,希望保持无状态)
  • 将其包含在电子邮件的链接中(安全性很差!)

可能有更好的方法。更改令牌包含一堆数据,其中包括包含新电子邮件地址的“目的” 。我可以以某种方式提取/解码该目的,还是将其作为哈希过程的一部分进行修饰?

1 个答案:

答案 0 :(得分:1)

答案只是坚持下去。无状态并不是真正的选择。但是,这并不意味着您需要用它污染用户子域。例如,您可以创建一个单独的实体,例如EmailChangeRequest,其中包含用于新电子邮件的道具,令牌以及可能的时间戳(主要用于修剪/过期)。在这里,该令牌不是用于验证,而是用于查找,因此可以将其视为表上的键。

简短地说,当用户单击链接时,您将通过令牌查找请求,从中获取新电子邮件,然后使用该新电子邮件和令牌呼叫ChangeEmailAsync

如果您真的反对任何形式的持久性,那么以前我个人都在模仿JWT。我之所以说“ -esque”,是因为传递一个完整的经过加密和签名的JWT作为查询或路由参数,这将使极其长网址用于您的确认链接,甚至可能接近请求限制。相反,我要做的是砍掉JWT的标头,因为标头主要用于跨客户端通信。在这种情况下,我可以安全地假设使用加密方法和发行者,而这是不必要的。

我进行的另一项更改是使用TOTP样式的令牌,而不是默认使用的加密哈希。这有助于进一步减小JWT令牌的大小,并且由于我正在加密JWT本身,因此内部的令牌本身是加密的并不重要。诸如电子邮件确认之类的令牌提供者可以位于ConfigureServices中的easily customized中,并且可以使用built-in TOTP token providers,因此这也是相对较低的摩擦。

我仍然认为保留它不一定不是一件坏事,尤其是如果您在用户子域之外使用单独的实体。但是,如果您不想走这种路线,伪JWT方法可能会更适合您的需求。