MVC Admin сброс пароля пользователя - PullRequest
0 голосов
/ 09 мая 2018

После большого количества возни и с некоторой превосходной помощью от ADyson , я получил эту работу.

В моей системе, когда пользователь с правами администратора входит в систему, появляется ссылка для входа в систему управления пользователями. Это предоставляет список пользователей, возможность создать другого пользователя, удалить его или изменить его данные.

Кроме того, когда ЛЮБОЙ пользователь входит в систему, он может изменить свой собственный пароль. Однако, если пользователь забывает свой пароль, администратор должен сбросить пароль. Я не отправляю им по электронной почте ссылку или что-нибудь необычное. В бите «Список пользователей» на экране администратора есть столбец «Действия», который содержит ссылки для редактирования, удаления, отображения сведений и сброса пароля.

У меня есть ApplicationUsersController, который содержит функции для редактирования, удаления и т. Д. У меня есть ряд представлений ApplicationUsers, которые называются «Создать», «Редактировать», «Удалить», «Детали», «Редактировать», «Индексировать». Большая часть этого кода была сгенерирована, когда я создал ApplicationUsersController и решил создать представления. Также есть ResetUserPasswordsViewModel. Вот вид ResetPassword:

@model ICWeb.Models.ResetUserPasswordViewModel

@{
    ViewBag.Title = "Reset User Password";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@ViewBag.Title</h2>


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true, "Please fix the errors displayed", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Id)

        <div class="form-group">
            @Html.LabelFor(model => model.NewPassword, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.NewPassword, new { htmlAttributes = new { @class = "form-control", @autofocus = "autofocus" } })
                @Html.ValidationMessageFor(model => model.NewPassword, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Reset Password" class="btn btn-default" />
            </div>
        </div>
    </div>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

В контроллере у меня есть:

    // GET: /ApplicationUsers/ResetPassword
    public ActionResult ResetPassword(string id)
    {
        return View(new ResetUserPasswordViewModel() { Id = id });
    }

    //POST: /ApplicationUsers/ResetPassword
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> ResetPassword(ResetUserPasswordViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        ApplicationDbContext context = new ApplicationDbContext();
        UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(context);
        UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(store);
        string userId = model.Id;
        string newPassword = model.NewPassword;
        string hashedNewPassword = UserManager.PasswordHasher.HashPassword(newPassword);
        ApplicationUser cUser = await store.FindByIdAsync(userId);
        await store.SetPasswordHashAsync(cUser, hashedNewPassword);
        await store.UpdateAsync(cUser);

        return RedirectToAction("Index");
    }

После долгих раздумий я снова сделал эту функцию. Теперь представление загружается, и я могу ввести 2 новых пароля. Когда я отправляю, запускается функция ResetPassword. Я могу видеть, когда я перебираю код, в котором есть пароли, которые я набрал, и, отредактировав функцию GET, чтобы заполнить модель идентификатором, я теперь получаю идентификатор пользователя. Весь доступ к контроллеру ограничен пользователями с правами администратора, поэтому если вы не являетесь администратором, вы ничего не можете сделать здесь.

В моем ResetUserPasswordModel у меня есть:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace ICWeb.Models
{
    public class ResetUserPasswordViewModel
    {
        public string Id { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "New password")]
        public string NewPassword { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm new password")]
        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }
}

Все отсортировано, и помощь была и очень ценится.

1 Ответ

0 голосов
/ 09 мая 2018

В системе, которую я разрабатываю (но еще не завершил или не протестировал), я написал это. Это работает, поэтому должна быть хорошей отправной точкой. Обратите внимание, что модель представления заботится о несовпадающих паролях, поэтому она уже предусмотрена.

Я использую Direct Injection для диспетчера пользователей - просто замените мой _userManager своим собственным экземпляром, однако вы его создадите.

@model Models.ResetPasswordViewModel
@{
    ViewBag.Title = "Reset password";
}

<div class="container">
    @if (ViewBag.Error != null)
    {
        <div class="alert-danger mb-2">Error(s) occured : @ViewBag.Error</div>
        @Html.ActionLink("Back to List", "AllUsers", null, new { @class = "btn btn-outline-primary" })
    }
    else
    {
        using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
        {
            @Html.AntiForgeryToken()

            @Html.ValidationSummary("", new { @class = "text-danger" })

            @Html.HiddenFor(x => x.Id)

            <div class="form-group">
                @Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control", @readonly = "" } })
            </div>

            <div class="form-group">
                @Html.LabelFor(m => m.Password, new { @class = "control-label" })
                @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.ConfirmPassword, new { @class = "control-label" })
                @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
            </div>

            <div class="form-group d-flex">
                @Html.ActionLink("Back to User Edit", "EditUser", "Account", new { userId = Model.Id }, new { @class = "btn btn-outline-primary" })

                <input type="submit" value="Reset Password" class="btn btn-primary ml-auto" />
            </div>
        }
    }
</div>


  public class ResetPasswordViewModel
    {
        [Display(Name = "User Id")]
        public string Id { get; set; }

        [Display(Name = "User Name")]
        public string UserName { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }


[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var user = _userManager.FindById(model.Id);

    IdentityResult result = null;

    if (user != null)
    {
        string code = await _userManager.GeneratePasswordResetTokenAsync(user.Id);

        result = await _userManager.ResetPasswordAsync(user.Id, code, model.Password);

        if (result.Succeeded)
        {
            return RedirectToAction("ResetPasswordConfirmation", "Account", model);
        }
    }

    // return errors
    var s = new System.Text.StringBuilder();
    //
    foreach (var e in result.Errors)
    {
        if (s.Length > 0)
        {
            s.Append(", ");
        }

        s.Append(e);
    }

    ViewBag.Error = s.ToString();

    return View();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...