Utilisateur.Identité.GetUserId () renvoie null après une connexion réussie

j'ai défini une variable temp pour obtenir l'identifiant de l'utilisateur courant, elle renvoie toujours null.

Voici la capture d'écran:

userId

Pourquoi?

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

UPDATE 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 sur le côté client:

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

SignalR sur le côté serveur:

public void SigninToSignalR()
    {
        // this's always null
        string userId = HttpContext.Current.User.Identity.GetUserId();
    }
26
demandé sur Tân Nguyễn 2015-11-27 10:02:37

7 réponses

en Fait, l'utilisateur est signé à - pas dans le contexte de l' la requête actuelle(POST /Account/Login demande), où User.Identity obtient ses données. Si vous voulez extraire l'id de l'utilisateur en train d'essayer de (et apparemment réussir) pour vous inscrire, vous devez le faire d'une autre façon, comme détourner un pas à l'intérieur de l'appel à SignInManager.PasswordSignInAsync. Si vous êtes à la mise en œuvre de votre propre MembershipProvider, ce devrait être facile.

Sinon, vous devrez attendre la prochaine demande(toute requête traitée par une méthode D'Action de Controller devrait faire l'affaire) utiliser User.Identity dans la façon dont vous voulez.

Quelques explications

quand votre Login la méthode est appelée, le contexte de la requête est déjà évalué et beaucoup de données sont disponibles. Par exemple, des en-têtes HTTP, des cookies, etc. C'est ici que se trouve toute l'information contextuelle., comme User.Identity.

quand vous appelez SignInManager.PasswordSignInAsync(...), ce n' affecter les valeurs de l' contexte de demande, parce que cela n'aurait aucun sens – depuis le navigateur n'a pas changé son esprit sur ce qu'il a envoyé quelques millisecondes plus tôt. Que cela affecte l' contexte de la réponse pour ajouter un cookie contenant un identifiant utilisateur et de session. Ce cookie est ensuite envoyé au navigateur, qui le renvoie ensuite au serveur pour chaque demande. Donc toutes les requêtes plus tard que celle-ci (jusqu'à ce que l'utilisateur se déconnecte ou le cookie est trop vieux) inclura des informations pour le User.Identity à interpréter.

24
répondu Anders Tornblad 2015-11-27 07:34:51

essayez simplement ceci:

string userId = SignInManager
.AuthenticationManager
.AuthenticationResponseGrant.Identity.GetUserId();
17
répondu Beedjees 2017-01-18 16:48:55

Vous pouvez, dans votre cas, l'utilisation d'autres données pour trouver l'utilisateur qui vient de se connecter. Puisque nous savons que le login est réussi et que le nom d'utilisateur est unique, ce qui suit fonctionnera;

 //
// 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
répondu Martijn Lentink 2016-10-07 07:38:02
HttpContext.User = await _signInManager.CreateUserPrincipalAsync(user);

après avoir signé, vous pouvez utiliser le sign in manager pour créer le principal utilisateur et assigner manuellement le HttpContext.Référence de l'utilisateur

cela vous permettra alors d'accéder à l'ID utilisateur comme vous le feriez avec un normal signé à la page

var userId = userManager.GetUserId(HttpContext.User);
2
répondu Dustin Gamester 2017-10-12 02:20:12

Oui, comme Anders l'a dit, Utilisateur.Identité et utilisateur.IsInRole ne fonctionnera pas dans la même action de connexion. Donc, vous devez rediriger vers une nouvelle action, donc à l'intérieur de l'action de connexion Ajouter:

return RedirectToAction ("MyNewLoginRoute", new {returl=returl });

ci-dessous 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 ajouter 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);
        }
    }

Espérons que cela pourrait aider quelqu'un.

1
répondu Bashar Abu Shamaa 2016-11-07 10:57:08

je reçois à l'utilisateur de faire ce qui suit juste après, connectez-vous:

var userId = SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.GetUserId();
var user = SignInManager.UserManager.Users.Where(x => x.Id.Equals(userId)).FirstOrDefault();
0
répondu wecky 2017-11-03 13:15:01

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 l'état d'authentification pour la requête courante.

0
répondu Dmitry Duka 2018-07-13 21:56:40