简体   繁体   中英

How to have users change their passwords after the first login?

The website that I have created requires to have Admin accounts create accounts for users. How would I go about having those users change their password after the first time they login? The problem is users will have a generic password designated to them, after they decide to login for the first time I would like them to have to change their password to something that is less generic.

Here is my login controller

  [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

    //
    // POST: /Account/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            var user = await UserManager.FindAsync(model.UserName, model.Password);
            if (user != null)
            {
                await SignInAsync(user, model.RememberMe);
                return RedirectToLocal(returnUrl);
            }

            else
            {
                ModelState.AddModelError("", "Invalid username or password.");
            }

        }

My login Model

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

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }



}

And the view

 <div class="container">
    <div class="col-md-8">
        <section id="loginForm">
            @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
            {
                @Html.AntiForgeryToken()
                <h4>Use a local account to log in.</h4>
                <hr />
                @Html.ValidationSummary(true)
                <div class="form-group">
                    @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
                    <div class="col-md-10">
                        @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
                        @Html.ValidationMessageFor(m => m.UserName)
                    </div>
                </div>
                <div class="form-group">
                    @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
                    <div class="col-md-10">
                        @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
                        @Html.ValidationMessageFor(m => m.Password)
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-offset-2 col-md-10">
                        <div class="checkbox">
                            @Html.CheckBoxFor(m => m.RememberMe)
                            @Html.LabelFor(m => m.RememberMe)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-offset-2 col-md-10">
                        <input type="submit" value="Log in" class="btn btn-default" />
                    </div>
                </div>
  1. Create new field in the Database ChangePassword in the [User] Table, default value equals to 1.
  2. When the new user log in make check if this user have field ChangePassword = 1 .
  3. If the user should change password, redirect him to page ChangePasswordPage in other case redirect to your default page.
  4. When he fill new password and click Change Password Button, set ChangePassword flag in [User] table to 0 and redirect him to your default page.

I've just had a similar problem. My system has the option of an admin creating users. What I did was to create the user with a randomly generated password.

The Confirmation Email normally has a URL which contains the email confirmation token. All I did was to include the confirmation AND email reset tokens:

string emailConfirmationCode = await 
UserManager.GenerateEmailConfirmationTokenAsync(userID);
        string passwordSetCode = await UserManager.GeneratePasswordResetTokenAsync(userID);


var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = userID, emailConfirmationCode = emailConfirmationCode, passwordSetCode = passwordSetCode }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(userID, subject,$"Please confirm your account by clicking <a href=\"{callbackUrl}\">here</a>");

then, in my confirmEmail action:

[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string userId, string emailConfirmationCode, string passwordSetCode = null )
{
    if (userId == null || emailConfirmationCode == null)
    {
        return View("Error");
    }
    var result = await UserManager.ConfirmEmailAsync(userId, emailConfirmationCode);

    if (result.Succeeded && !string.IsNullOrEmpty(passwordSetCode))
    {
        return RedirectToAction("ResetPassword", "Account", new { userId = userId, code = passwordSetCode, firstPassword = true  });
    }

    return View(result.Succeeded ? "ConfirmEmail" : "Error");
}

Note that I use firstPassword so that I can show a different view to Forgot Password

[AllowAnonymous]
public ActionResult ResetPassword(string code, bool firstPassword = false)
{
    if (code == null)
        return View("Error");
    return firstPassword? View("FirstPassword") : View();
}

This way, the only way they can log in is by confirming their email AND setting their password. IF they somehow don't follow through with the reset, they'd need to do the forgot password process from scratch. Re-clicking their link gives me a token error the second time around.

If you have a database field tracking his last logged in, it would be easy to implement a simple solution like this:

  1. First time they come with a generic password, last logged in field will be null.
  2. You can check if the last logged in field is null, they have never changed their password, so you can force them to change it (you can check if new password is not the same as before) and let them login as well. Now user has last logged in date set to not null. He is now set to login with new password going forward.

Force them to change their password. As long as they haven't changed there "once-off" password, no access to the site. let them type 2 their new password, check if they are equal, then update their password. Somewhere,probably in your database you have to keep track if they havechanged their once-off password.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM