User.Identity.GetUserId() returns null after successful login
You could, in your case use other data to find the user that just logged in. Since we know that the login is successful and username is unique the following will work;
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return Json(new { success = false, ex = "Fail to login." });
}
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, isPersistent: true, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
string userId = UserManager.FindByName(model.Email)?.Id;
return Json(new { success = true });
case SignInStatus.Failure:
return Json(new { success = false, ex = "Email or password was incorrect." });
default:
return Json(new { success = false, ex = "Fail to login." });
}
}
Actually, the user is not signed in - not in the context of the current request (the POST /Account/Login
request), which is where User.Identity
gets its data. If you want to extract the id of the user currently trying to (and apparently succeeding) to sign in, you need to do that in some other way, like hijacking some step inside the call to SignInManager.PasswordSignInAsync
. If you are implementing your own MembershipProvider
, this should be easy.
Otherwise, you will have to wait for the next request (any request handled by some Controller's Action method should do fine) to use User.Identity
in the way you want to.
Some added explanation
When your Login
method gets called, the request context is already evaluated and a lot of data is available. For example HTTP headers, cookies and so on. This is where all the context information is found, like User.Identity
.
When you call SignInManager.PasswordSignInAsync(...)
, this does not affect the values of the request context, because this would make no sense – since the browser has not changed its mind about what it sent a few milliseconds ago. What it does affect is the response context to add a cookie containing some user and session id. This cookie is then sent to the browser, which then sends it back to server for each successive request. So all requests later than this one (until the user signs out or the cookie gets too old) will include information for the User.Identity
to interpret.
Simply try this :
string userId = SignInManager
.AuthenticationManager
.AuthenticationResponseGrant.Identity.GetUserId();