J'écris MVC 5 et j'utilise Identity 2.0.
Maintenant, je tente de réinitialiser le mot de passe. Mais je reçois toujours l'erreur "invalid token" pour réinitialiser le jeton de mot de passe.
public class AccountController : Controller
{
public UserManager<ApplicationUser> UserManager { get; private set; }
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
et j'ai défini 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;
}
je génère un mot de passe réinitialisé avant d'envoyer du courrier
[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
}
}
je clique sur le lien dans le courrier et je reçois le jeton passwordreset et en utilisant
var result = await UserManager.ResetPasswordAsync(model.UserId, model.PasswordToken, model.NewPassword);
le résultat est toujours faux et le message "Jeton non valide" . Où dois-je réparer?
UserManager.GeneratePasswordResetTokenAsync()
renvoie très souvent une chaîne contenant des caractères '+'. Si vous transmettez des paramètres par chaîne de requête, c'est la cause (le caractère '+' est un espace dans la chaîne de requête dans l'URL).
Essayez de remplacer les espaces dans model.PasswordToken
par des caractères '+'.
[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
}
}
Et lors de la réinitialisation du mot de passe, décoder le jeton HttpUtility.UrlDecode(token);
J'ai constaté que l'erreur 'Invalid Token' se produisait également lorsque la colonne SecurityStamp avait la valeur NULL pour l'utilisateur figurant dans la table AspNetUsers de la base de données . SecurityStamp ne serait pas NULL avec le MVC 5 prêt à l'emploi Code d'identité 2.0, cependant un bogue avait été introduit dans notre code lors de la personnalisation de AccountController qui effaçait la valeur du champ SecurityStamp.
Beaucoup de réponses ici URLEncode le jeton avant d'envoyer pour éviter le fait que le jeton (chaîne codée en base 64) contient souvent le caractère '+'. Les solutions doivent également prendre en compte le fait que le jeton se termine par '=='.
Je me débattais avec ce problème et il s'est avéré que de nombreux utilisateurs d'une grande entreprise utilisaient Scanmail Trustwave Link Validator (r), qui ne codait ni ne décodait de manière symétrique les jarretières URLEncodées dans le lien de messagerie (au moment de la rédaction).
Le moyen le plus simple était d'utiliser la réponse de Mateusz Cisek, d'envoyer un jeton non URLEncodé et de simplement remplacer les espaces par +. Dans mon cas, cela a été fait dans un SPA angulaire afin que le Javascript devienne $routeParams.token.replace(/ /g,'+')
.
Si vous utilisez AJAX pour envoyer le jeton et lancez votre propre algorithme d'analyse de chaîne de requête, de nombreux exemples divisent chaque paramètre en "=", ce qui n'inclura bien sûr pas le "==" à la fin de le jeton. Facile à contourner en utilisant l’une des solutions regex ou en recherchant le premier '=' uniquement.