Подтвердить что ты не робот

Идентификационный пароль reset недействителен

Я пишу MVC 5 и используя Identity 2.0.

Теперь я пытаюсь использовать reset пароль. Но я всегда получаю ошибку "недопустимый токен" для токена пароля reset.

    public class AccountController : Controller
{
    public UserManager<ApplicationUser> UserManager { get; private set; }

    public AccountController()
        : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
    {
    }

и я установил DataProtectorTokenProvider,

        public AccountController(UserManager<ApplicationUser> userManager)
    {   
        //usermanager config
        userManager.PasswordValidator = new PasswordValidator { RequiredLength = 5 };  
        userManager.EmailService = new IddaaWebSite.Controllers.MemberShip.MemberShipComponents.EmailService(); 

        var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider();
        userManager.UserTokenProvider = new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<ApplicationUser>(provider.Create("UserToken"))
                                                    as IUserTokenProvider<ApplicationUser, string>;




        UserManager = userManager;

    }

Я создаю пароль reset перед отправкой почты

 [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> ManagePassword(ManageUserViewModel model)
    {
        if (Request.Form["email"] != null)
        {
          var email = Request.Form["email"].ToString();
          var user = UserManager.FindByEmail(email);
          var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
           //mail send
        }
   }

Я нажимаю ссылку по почте, и я получаю токен для сброса пароля и используя

var result = await UserManager.ResetPasswordAsync(model.UserId, model.PasswordToken, model.NewPassword);

результат всегда ложный, и он говорит "Недопустимый токен". Где я должен исправить?

4b9b3361

Ответ 1

UserManager.GeneratePasswordResetTokenAsync() очень часто возвращает строку, содержащую символы "+" . Если вы передаете параметры по строке запроса, это причина (символ "+" - это пробел в строке запроса в URL-адресе).

Попробуйте заменить символы пробела в model.PasswordToken символами "+" .

Ответ 2

[HttpPost]
[ValidateAntiForgeryToken]
publicasync Task<ActionResult> ManagePassword(ManageUserViewModel model)
{
    if (Request.Form["email"] != null)
    {
      var email = Request.Form["email"].ToString();
      var user = UserManager.FindByEmail(email);
      var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
       //before send mail
      token = HttpUtility.UrlEncode(token);   
  //mail send

    }
}

И на пароле reset action decode token HttpUtility.UrlDecode(token);

Ответ 3

Я обнаружил, что ошибка "Недопустимый токен" также возникает, когда столбец SecurityStamp имеет значение NULL для пользователя в таблице AspNetUsers в базе данных. SecurityStamp не будет NULL с готовым кодом MVC 5 Identity 2.0, однако ошибка была введена в нашем коде при выполнении некоторой настройки AccountController, которая очистила значение в поле SecurityStamp.

Ответ 4

Многие ответы здесь URLEncode токен перед отправкой, чтобы обойти тот факт, что токен (являющийся строкой с кодировкой базы 64) часто содержит символ "+". Решения также должны учитывать, что токен заканчивается на "==".

Я боролся с этой проблемой, и оказалось, что многие пользователи в крупной организации использовали Scanmail Trustwave Link Validator (r), который не был симметричным кодированием и декодированием URLEncoded stings в ссылке электронной почты (на момент написания).

Самый простой способ - использовать ответ Mateusz Cisek и отправить не токены URLEncoded и просто заменить символы пробела на+. В моем случае это было сделано в angular SPA, поэтому Javascript становится $routeParams.token.replace(/ /g,'+').

Предостережение здесь будет заключаться в том, что если AJAX отправляет токен и катит собственный алгоритм синтаксического анализа строки запроса - многие примеры разделяют каждый параметр на '=', который, конечно же, не будет включать '==' в конце маркер. Легко работать, используя одно из регулярных выражений или ищет только "1 =".