Идентификационный пароль 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);
результат всегда ложный, и он говорит "Недопустимый токен".
Где я должен исправить?
Ответы
Ответ 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 =".