MVC 5 ASP.NET Identity 2: Capture user's prefe

2020-04-11 19:04发布

问题:

I am using the Identity 2.0 Sample.

I get that by setting isPersistent to true in ExternalLoginCallback action method, the browser will automatically log the user in the next time (within limits) they visit using the same browser. I know that if the user's "remember me" preference was captured and passed to the ExternalLogin action method that it could be put into returnUrl and accessed in ExternalLoginCallback. But how do I get their preference to the ExternalLogin action method?

I don't get in this case how to put a checkbox on the LoginView page and wire things up so that I can process it in the ExternalLogin action method. How can I accomplish this?

回答1:

Check out the AccountController.ExternalLoginConfirmation action and note the call to await SignInHelper.SignInAsync(user, isPersistent: false, rememberBrowser: false). You can set those values to true, or you can update the ExternalLoginConfirmationViewModel and corresponding ExternalLoginConfirmation view to let the user decide.

BTW: isPersistent will persist the users session across closing and reopening their browser. The rememberBrowser argument is particular to two factor authentication and it sounds like should be left false for your circumstance.

Tangentially related Supporting remember me with two factor authentication



回答2:

Don't delete any code, just change as follows:

In AccountViewModels, edit to match:

public class ExternalLoginViewModel 
    {
        public string Action { get; set; }
        public string ReturnUrl { get; set; }
        public string RemembermeExtnl { get; set; }
    }

In Account Controller, edit to match:

public ActionResult Login(string returnUrl)
    {   
        ViewBag.ReturnUrl = returnUrl;
        ViewBag.RemembermeExtnl = "f";
        return View();          
    }

public ActionResult ExternalLogin(string provider, string returnUrl, string remembermeExtnl) 
    {
        // Request a redirect to the external login provider
        return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl, remembermeExtnl = remembermeExtnl }));
    }


public async Task<ActionResult> ExternalLoginCallback(string returnUrl, string remembermeExtnl)
    {
    ...
        var result = await SignInHelper.ExternalSignIn(loginInfo, isPersistent: remembermeExtnl=="t"); 
    ...
    }

In Login view, edit to match:

<section id="socialLoginForm">
    @Html.Partial("_ExternalLoginsListPartial", new PG.Models.ExternalLoginViewModel() { Action = "ExternalLogin", ReturnUrl = ViewBag.ReturnUrl, RemembermeExtnl = ViewBag.RemembermeExtnl })                
     <input type="checkbox" id="cbxRemExt" />  Remember me  
</section>

In Login view, add this:

<script>
// ** change to eq(1) (2 places!) if your social login form is the second form on the page,
//  keep as below if first form is your social login form **
  $("#cbxRemExt").change(function () {
      var isChecked = $(this).is(":checked");
       var actionstring = $('form').eq(0).attr('action');          
       actionstring = actionstring.replace('RemembermeExtnl=' + (isChecked ? 'f' : 't'), 'RemembermeExtnl=' + (isChecked ? 't' : 'f'))
       $('form').eq(0).attr('action', actionstring);
  });
</script>

In _ExternalLoginListPartial:

string action = Model.Action;
string returnUrl = Model.ReturnUrl;
string remembermeExtnl = Model.RemembermeExtnl;
using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl, RemembermeExtnl = remembermeExtnl }))