Pregunta User.Identity.GetUserId () devuelve null después de iniciar sesión correctamente


Definí una variable de temperatura para obtener el ID de usuario actual, siempre devuelve nulo.

Aquí está la instantánea:

userId

¿Por qué?

ACTUALIZAR:

    //
    // 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 = User.Identity.GetUserId();
                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." });
        }
    }

ACTUALIZACIÓN 2:

En el lado del cliente, uso ajax para conectarme a /Account/Login:

var loginAjax = function (email, password, callback) {        
        $.ajax({
            url: '/Account/Login',
            type: 'POST',
            data: { Email: email, Password: password },
            success: function (data) {
                $('body').css('cursor', 'default');
                if (data.success) {                    
                    callback(true)
                } else {
                    $('#login-error').text(data.ex)
                }
            },
            error: function () {                
                $('#login-error').text('Không thể kết nối đến máy chủ.')
            }
        });
        callback(false)
    };


// I've got email and password in another function to check valid or not
loginAjax(email, password, function (success) {
            $('body').css('cursor', 'default');
            switch (success) {
                case true:
                    signin(function () {
                        $('.login').html('');
                        window.location.href = '/?type=Promotion';
                    });
                    break
                case false:                    
                    $('#Email-active').hide();
                    $('#Password-active').hide();
                    $('#Password').val('');
                    $('#login-btn').removeClass('disabled').attr('onclick', '$(this).addClass("disabled").removeAttr("onclick"); running()');
                    break
            }
        });

SignalR en el lado del cliente:

var signalR = $.connection.chat;
var signin = function (callback) {
            $.connection.hub.start().done(function () {
                signalR.server.signinToSignalR();
                callback()
            })
        };

SignalR en el lado del servidor:

public void SigninToSignalR()
    {
        // this's always null
        string userId = HttpContext.Current.User.Identity.GetUserId();
    }

25
2017-11-27 07:02


origen


Respuestas:


En realidad, el usuario es no firmado, no en el contexto de la solicitud actual  (el POST /Account/Login solicitud), cuál es dónde User.Identity obtiene sus datos. Si desea extraer la identificación del usuario que intenta actualmente (y al parecer teniendo éxito) para iniciar sesión, debe hacerlo de otra forma, como secuestrar algún paso dentro de la llamada a SignInManager.PasswordSignInAsync. Si está implementando su propio MembershipProvider, esto debería ser fácil.

De lo contrario, tendrá que esperar la próxima solicitud  (cualquier solicitud manejada por algún método de Acción del Controlador debería funcionar bien) usar User.Identity en la forma en que quieres.

Alguna explicación adicional

Cuando tu Login se llama al método, el contexto de solicitud ya está evaluado y hay una gran cantidad de datos disponibles. Por ejemplo, encabezados HTTP, cookies, etc. Aquí es donde se encuentra toda la información de contexto, como User.Identity.

Cuando usted llama SignInManager.PasswordSignInAsync(...), esto hace no afectar los valores de la contexto de solicitud, porque esto no tendría sentido, ya que el navegador no ha cambiado de opinión acerca de lo que envió hace unos pocos milisegundos. Lo que sí afecta es el contexto de respuesta agregar un Galleta que contiene alguna identificación de usuario y sesión. Esta cookie luego se envía al navegador, que luego la envía al servidor para cada solicitud sucesiva. Entonces, todas las solicitudes posteriores a esta (hasta que el usuario cierre la sesión o la cookie se vuelva demasiado vieja) incluirá información para el User.Identity interpretar.


23
2017-11-27 07:13



Simplemente prueba esto:

string userId = SignInManager
.AuthenticationManager
.AuthenticationResponseGrant.Identity.GetUserId();

15
2018-01-18 16:48



En su caso, podría utilizar otros datos para encontrar al usuario que acaba de iniciar sesión. Como sabemos que el inicio de sesión es exitoso y el nombre de usuario es único, lo siguiente funcionará;

 //
// 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." });
    }
}

7
2017-10-07 07:38



HttpContext.User = await _signInManager.CreateUserPrincipalAsync(user);

Después de iniciar sesión, puede usar el administrador de inicio de sesión para crear el principal del usuario y asignar manualmente la referencia HttpContext.User

Esto le permitirá acceder a la identificación de usuario como lo haría con una página de inicio de sesión normal.

var userId = userManager.GetUserId(HttpContext.User);

2
2017-10-11 21:25



Sí, como dijo Anders, User.Identity y User.IsInRole no funcionarán dentro de la misma acción de inicio de sesión. Por lo tanto, debe redireccionar a una nueva acción, de modo que dentro de la acción de inicio de sesión agregue:

devuelve RedirectToAction ("MyNewLoginRoute", nuevo {returnUrl = returnUrl});

a continuación se muestra un ejemplo de código:

        var result =  SignInManager.PasswordSignIn(model.Email, model.Password, model.RememberMe, shouldLockout: false);

        switch (result)
        {
            case SignInStatus.Success:

// below is the new line modification
      return RedirectToAction("LoginRoute", new {returnUrl=returnUrl });

Y ahora agregue una nueva acción LoginRoute de la siguiente manera:

 // below method is new to get the UserId and Role
 public ActionResult LoginRoute(string returnUrl)  //this method is new
    {
        if (String.IsNullOrWhiteSpace(returnUrl))
        {
            if (User.IsInRole("Admin"))
            {
                return RedirectToLocal("/Admin");
            }
            else if (User.IsInRole("Partner"))
            {
                return RedirectToLocal("/Partner/Index/");
            }
            else if (User.IsInRole("EndUser"))
            {
                ApplicationDbContext db = new ApplicationDbContext();

            // know the partner
                int partnerID = db.Users.Where(x => x.UserName == User.Identity.Name).FirstOrDefault().PartnersTBLID;
                return RedirectToLocal("/Partner/List/" + partnerID.ToString());
            }

        }
        else
        {
            return RedirectToLocal(returnUrl);
        }
    }

Espero que esto pueda ayudar a alguien.


1
2017-09-22 11:15



El usuario hace lo siguiente justo después de iniciar sesión:

var userId = SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.GetUserId();
var user = SignInManager.UserManager.Users.Where(x => x.Id.Equals(userId)).FirstOrDefault();

0
2017-11-03 13:15



Esto es lo que funcionó para mí:

await SignInManager.SignInAsync(user, isPersistent: true, rememberBrowser: false);

AuthenticationManager.User = new GenericPrincipal(AuthenticationManager.AuthenticationResponseGrant.Identity, null);

Una vez ejecutado, obtiene el estado autenticado para la solicitud actual.


0
2017-07-13 21:56