Question User.Identity.GetUserId () renvoie null après une connexion réussie


J'ai défini une variable temporaire pour obtenir l'ID utilisateur actuel, il renvoie toujours null.

Voici l'instantané:

userId

Pourquoi?

METTRE À JOUR:

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

MISE À JOUR 2:

Côté client, j'utilise ajax pour me connecter à /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 du côté client:

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

SignalR côté serveur:

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

25
2017-11-27 07:02


origine


Réponses:


En fait, l'utilisateur est ne pas signé - pas dans le contexte de la demande actuelle  (la POST /Account/Login demande), qui est où User.Identity obtient ses données. Si vous voulez extraire l'ID de l'utilisateur qui tente actuellement de (et apparemment réussi) pour vous connecter, vous devez le faire d’une autre manière, comme détourner une étape de l’appel vers SignInManager.PasswordSignInAsync. Si vous implémentez votre propre MembershipProvider, cela devrait être facile.

Sinon, vous devrez attendre la prochaine demande  (Toute demande gérée par la méthode Action de certains contrôleurs devrait bien se passer) utiliser User.Identity comme vous le souhaitez.

Quelques explications supplémentaires

Quand ton Login méthode est appelée, le contexte de la demande est déjà évalué et beaucoup de données sont disponibles. Par exemple les en-têtes HTTP, les cookies, etc. C'est là que se trouvent toutes les informations de contexte, comme User.Identity.

Quand vous appelez SignInManager.PasswordSignInAsync(...), cela ne ne pas affecter les valeurs de la contexte de demande, car cela n'aurait aucun sens - puisque le navigateur n'a pas changé d'avis sur ce qu'il a envoyé il y a quelques millisecondes. Ce qu'il affecte est le contexte de réponse ajouter un biscuit contenant un identifiant utilisateur et session. Ce cookie est ensuite envoyé au navigateur, qui le renvoie ensuite au serveur pour chaque requête successive. Donc, toutes les demandes plus tard que celle-ci (jusqu'à ce que l'utilisateur se déconnecte ou que le cookie soit trop vieux) comprendra des informations pour le User.Identity interpréter.


23
2017-11-27 07:13



Essayez simplement ceci:

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

15
2018-01-18 16:48



Vous pourriez, dans votre cas, utiliser d'autres données pour trouver l'utilisateur qui vient de se connecter. Comme nous savons que la connexion est réussie et que le nom d'utilisateur est unique, les éléments suivants fonctionneront;

 //
// 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);

Après vous être connecté, vous pouvez utiliser le gestionnaire de connexion pour créer le principal utilisateur et attribuer manuellement la référence HttpContext.User.

Cela vous permettra alors d'accéder à l'identifiant de l'utilisateur comme vous le feriez avec une page de signature normale.

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

2
2017-10-11 21:25



Oui, comme Anders l'a dit, User.Identity et User.IsInRole ne fonctionneront pas dans la même action de connexion. Donc, vous devez rediriger vers une nouvelle action, donc l'action de connexion interne ajoute:

renvoyer RedirectToAction ("MyNewLoginRoute", nouveau {returnUrl = returnUrl});

ci-dessous est un exemple de code:

        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 });

Et maintenant, ajoutez une nouvelle action LoginRoute comme ci-dessous:

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

J'espère que cela pourrait aider quelqu'un.


1
2017-09-22 11:15



Je demande à l’utilisateur de faire ce qui suit après la connexion:

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



Voici ce qui a fonctionné pour moi:

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

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

Une fois exécuté, vous obtenez un état authentifié pour la requête en cours.


0
2017-07-13 21:56