【问题标题】:"passwordResetLink" link failed to generate in asp.net core“passwordResetLink”链接无法在 asp.net 核心中生成
【发布时间】:2021-12-05 06:53:24
【问题描述】:

我想在我的应用程序(Asp.Net Core 2.2)中创建一个忘记密码系统。我成功生成了一个令牌。但问题是当我生成 passwordResetLink 时它为空。

var passwordResetLink = Url.Action("ResetPassword", "Account",
                    new { email = model.Email, token = token }, Request.Scheme);

我不明白我的emailtoken 不为空,但为什么passwordResetLink 为空?

这是我的所有代码:-

 [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await userManager.FindByEmailAsync(model.Email);
                
                if (user != null)
                {
                    // Generate the reset password token
                    var token = await userManager.GeneratePasswordResetTokenAsync(user);
                    
                    var passwordResetLink = Url.Action("ResetPassword", "Account",
                    new { email = model.Email, token = token }, Request.Scheme); //here is the main problem.why it's null?
                  
                     return View("ForgotPasswordConfirmation");
                }

                return View("ForgotPasswordConfirmation");
            }

            return View(model);
        }

Startup.cs 文件(ConfigureServices):-

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IBraintreeService, BraintreeService>();
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout = TimeSpan.FromMinutes(10);
                //options.Cookie.HttpOnly = true;
                // Make the session cookie essential
                options.Cookie.IsEssential = true;
            });

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddIdentity<IdentityUser, IdentityRole>()
                .AddDefaultUI(UIFramework.Bootstrap4).AddDefaultTokenProviders()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

这是我的输出:-

【问题讨论】:

  • Url.Action() 如果找不到与提供的参数匹配的路由,将返回 null。 你有一个AccountController 和一个ResetPassword 操作方法,接受一个emailtoken 参数吗?
  • @CodeCaster 感谢您的回复。我有 AccountController 和 ResetPassword 方法。我也在我的项目中使用了Area
  • AccountController在哪个区域?
  • @CodeCaster 我的区域名称是Display1
  • 然后使用new { email = model.Email, token = token , area = "Display1" }

标签: c# asp.net-mvc asp.net-core asp.net-core-mvc asp.net-core-identity


【解决方案1】:

你应该像这样创建两个类:

public class ResetPasswordTokenProvider<TUser> : DataProtectorTokenProvider<TUser> where TUser : class
{
    public ResetPasswordTokenProvider(IDataProtectionProvider dataProtectionProvider,
            IOptions<ResetPasswordTokenProviderOptions> options)
            : base(dataProtectionProvider, options)
    {
    }
}
public class ResetPasswordTokenProviderOptions : DataProtectionTokenProviderOptions
{
    public ResetPasswordTokenProviderOptions()
    {
        Name = "ResetPasswordDataProtectorTokenProvider";
        TokenLifespan = TimeSpan.FromDays(1);
    }
}

并将创建的类注册到身份提供者:

services.AddIdentity<IdentityUser, IdentityRole>(identityOptions =>
            {
                identityOptions.Tokens.ProviderMap.Add("ResetPassword",
                    new TokenProviderDescriptor(typeof(ResetPasswordTokenProvider<IdentityUser>)));
                identityOptions.Tokens.PasswordResetTokenProvider = "ResetPassword";
            })
            .AddTokenProvider<ResetPasswordTokenProvider<IdentityUser>>("ResetPassword")
            .AddEntityFrameworkStores<ApplicationDbContext>();

【讨论】:

    【解决方案2】:

    你可以试试这个替代方法。

    public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
    {
    
      var code = await userManager.GeneratePasswordResetTokenAsync(user);
      code = System.Web.HttpUtility.UrlEncode(code);
      var token = code;
      var datUrl = "https://localhost:xxxx/Customer/Account/ResetPassword?" + "email=" + 
      model.Email + "&token=" + token;
    
      ....
    
    

    它将解决您的问题。

    【讨论】:

    • 我们不要硬编码 URL 并称之为解决问题。
    • @CodeCaster 这就是为什么我已经说过这个答案是另一种选择。看看上面。
    • 除非它不是。它不可维护,迟早会坏掉。
    • “我的车无法启动” - “或者,您可以尝试推动它”
    猜你喜欢
    • 1970-01-01
    • 2021-11-05
    • 2013-07-24
    • 2017-08-19
    • 2019-07-10
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多