当前位置: 首页 > 知识库问答 >
问题:

ASP。net身份v2。0.0电子邮件确认/重置密码错误

薛彭薄
2023-03-14

我们刚刚启动了我们的ASP。NETMVC(使用Identity 2.0)web应用程序6天前已经有超过5000人注册了帐户,太棒了!

问题是3-5%点击确认电子邮件链接的用户(似乎也是重置密码)会出现错误屏幕,大概是因为他们有一个无效的令牌。

我在StackOverflow上读到,您需要对url进行编码,以避免特殊字符将其丢弃,然后在验证之前对其进行解码。不过,我这样做没有效果,一些用户仍然在他们的验证令牌上出错。

我还了解到,拥有不同的MachineKey可能是令牌未被视为有效的一个原因。一切都是托管在Azure上的,所以我认为(并看到了)它已经或应该得到处理

因此,在过去的6天里,有30-50人向我们发送了关于问题的电子邮件,当我试图提出解决方案并将我的确认邮件操作设置为以下内容时,我感到绝望:

[AllowAnonymous]
        public ActionResult ConfirmEmail(string userId = null, string code = null)
        {
            if (userId == null || code == null)
            {
                return View("Error");
            }
            else
            {
                var emailCode = UserManager.GenerateEmailConfirmationToken(userId);
                var result = UserManager.ConfirmEmail(userId, emailCode);
                return View(result.Succeeded ? "ConfirmEmail" : "Error");
            }   
        }

我想这是不可能失败的,它只是生成一个令牌,然后立即使用它——但不知何故它仍然失败(失败是指用户看到错误页面)

到目前为止,我对可能解决方案的最佳猜测是SO(Asp.NET-标识2-无效令牌错误,中途)

每次创建(或新编辑)UserManager时,都会生成一个新的dataProttionProvider。因此,当用户收到电子邮件并单击链接时,会计控制器已经不是旧的,_userManager和它的令牌提供商也不是。因此,新的令牌提供程序将失败,因为它的内存中没有该令牌。因此,我们需要为令牌提供程序使用单个实例。

但这已经不再是OWIN所有东西所必需的了,对吧?

这真的是问题吗?如果是这样,什么鬼ASP. net身份团队?为什么啊?

我改变了一些事情:

默认注册操作建议通过以下方式发送确认电子邮件:

var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);

在我的注册行动中有以下内容

string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Confirm your XXXXXXX account");

然后我在SendEailConfirmationTokenAsync中指定以下内容

private async Task<string> SendEmailConfirmationTokenAsync(string userID, string subject)
        {
            string code = await UserManager.GenerateEmailConfirmationTokenAsync(userID);
            var callbackUrl = Url.Action("ConfirmEmail", "Account",
               new { userId = userID, code = code }, protocol: Request.Url.Scheme);

        // construct nice looking email body

            await UserManager.SendEmailAsync(userID, subject, htmlBody);

                return callbackUrl;
    }

对我来说,这两个部分是等价的,不是吗?

然后我唯一能想到的另一件事就是我是如何添加我的db类的,但是这不应该影响UserManager,对吗?

my account controller的顶部如下所示(这就是MS提供的示例如何添加我的数据库):

private readonly SiteClasses db = new SiteClasses();

        public AccountController()
        {
        }

        public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
        {
            UserManager = userManager;
            SignInManager = signInManager;
        }

        private ApplicationUserManager _userManager;
        public ApplicationUserManager UserManager
        {
            get
            {
                return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            private set
            {
                _userManager = value;
            }
        }

    ...

我们正在使用推荐的电子邮件提供商sendgrid,我个人从未能够复制这个问题(在手动创建了约60个测试帐户之后),大多数人似乎相处得很好。

部分原因可能是用户自己造成的错误,但这似乎发生在一群不熟悉技术的人身上,他们只是点击链接,期望它像普通的确认邮件一样工作。大多数用户都是从他们的苹果手机来找我们的,我想他们只是在使用苹果的默认邮件客户端,但不是积极的。我不知道任何垃圾邮件过滤器或电子邮件设置会从链接中删除查询字符串值。

我有点渴望得到答案,因为我正试图启动一个伟大的新公司,但却被ASP挂断了。net Identity的技术性问题或bug或其他正在发生的事情。

建议在哪里看或如何设置的东西将不胜感激

共有2个答案

裴韬
2023-03-14

我最终在AspNetUsers表中手动确认电子邮件,而不是动态创建新令牌并尝试使用UserManager。确认邮件。

[HandleError(ExceptionType = typeof(HttpException), View = "ConfirmEmail")]
public ActionResult ConfirmEmail(string userId = null, string code = null)
    {
        if (userId == null || code == null)
        {
            return View("Error");
        }
        var result = await UserManager.ConfirmEmailAsync(userId, code);
        if (result.Succeeded)
        {
            return View("ConfirmEmail");
        }
        else
        {
            var user = DBContext.Users.Find(userId);
            user.EmailConfirmed = true;
            DBContext.SaveChanges();
            throw new HttpException(result.Errors.FirstOrDefault());
        } 


    }

我还使用了[HandleError(ExceptionType=typeof(HttpException),View=“ConfirmEmail”)]来记录错误,但仍将使用指向ConfirmEmail页面。

这不是一个很好的解决方案,但我还没有找到任何方法来解决这个问题。

漆雕伟志
2023-03-14

我当前将电子邮件作为URL的一部分发送。

我们有一位客户在tufts拥有转发电子邮件帐户。edu进入gmail。com而且它必须重写她的电子邮件地址,这是URL的一部分-这很可怕,但我看不出它还可能做什么。

如果我能证实这一点,这是另一件需要注意的事情。

 类似资料:
  • 我已经建立了一个ASP。具有身份的NET Core 5 web应用程序。一切正常。唯一的问题是,当新用户在他们的电子邮件确认中点击链接后,网站上显示的消息是“确认电子邮件”。确认有效,但消息让用户感到困惑。 发送到的地址是: https://Baseurl/身份/帐户/确认Email? userId=******** Identity/Account文件夹中的任何文件都不包含显示的邮件。是否可以更

  • 我想为新用户设置一封确认电子邮件。 所以当调试时,单击链接时,userId是可以的,但“code”输入参数为空,所以 是真的,然后执行 发送给注册用户的电子邮件如下所示: 请单击此链接确认您的帐户:https://localhost:44314/Account/ConfirmEmail?userId=3ec7ac6a-3329-4821-a09b-aa4843598eaa 编辑:链接包含 实际上,

  • 我已经设法使用ASP. NET核心身份为我的项目设置了注册和登录。一切正常,但有一件小事真的困扰着我。 由于这是一个简单的项目,我不想通过向用户发送电子邮件来配置帐户确认,因此我使用默认模板,用户被重定向到帐户。RegisterConfirmation,他们可以选择一个链接来确认帐户,该链接将用户重定向到/Identity/account/ConfirmEmail,这是一个只有标题的空白页面。我不

  • 如何获取新ASP中用户的密码。网络身份识别系统?或者如何在不知道当前密码(用户忘记密码)的情况下重置?

  • 我只是在我的项目中添加了MVC 5的“忘记密码”部分,在收到邮件后我无法更改密码。 错误:在应用程序中= 在Visual Studio中= 错误来源代码: 我在stackoverflow和其他方面尝试了很多东西,但都没有成功。 如果你知道我为什么会出现这个错误:) 我使用在创建ASP时提出的基本模板。NET web app。我可以上传你想要的所有代码文件,只要问你需要什么帮助我,我会在2分钟内上传

  • 我们研发的App可以在用户确认访问我们的分支机构后向其发送电子邮件。当我们使用以下Gmail配置时,它可以正常工作:电子邮件:ainetwgdocs@gmail.comPasswd:XXXXX SMTP服务器:smtp.gmail.com端口:587但是,当我们尝试使用基于域的帐户时,它根本不起作用。我们使用以下参数:电子邮件:contact@ainetw.comPasswd:XXXXX SMTP