web-dev-qa-db-de.com

User.Identity.GetUserId () gibt nach erfolgreicher Anmeldung Null zurück

Ich habe eine temporäre Variable definiert, um die aktuelle Benutzer-ID abzurufen. Sie gibt immer null zurück.

Hier ist die Momentaufnahme:

 userId

Warum?

UPDATE:

    //
    // 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:

Auf Clientseite verwende ich ajax, um eine Verbindung zu /Account/Login herzustellen:

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 auf Kundenseite:

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

SignalR auf Serverseite:

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

Tatsächlich ist der Benutzer nicht angemeldet - nicht im Kontext von der aktuellen Anforderung (der POST /Account/Login-Anforderung), wobei User.Identity seine Daten erhält. Wenn Sie die ID des Benutzers extrahieren möchten, der gerade versucht, sich mit (und scheinbar erfolgreich) anzumelden, müssen Sie dies auf eine andere Weise tun, z. B. einen Schritt in den Aufruf von SignInManager.PasswordSignInAsync hijacken. Wenn Sie Ihre eigene MembershipProvider implementieren, sollte dies einfach sein.

Andernfalls müssen Sie auf die nächste Anforderung warten (jede Anforderung, die von der Action-Methode eines Controllers verarbeitet wird, sollte in Ordnung sein), um User.Identity in der gewünschten Weise zu verwenden.

Einige zusätzliche Erklärung

Wenn Ihre Login-Methode aufgerufen wird, wird der Anforderungskontext bereits ausgewertet, und es stehen viele Daten zur Verfügung. Zum Beispiel HTTP-Header, Cookies usw. Hier finden Sie alle Kontextinformationen wie User.Identity.

Wenn Sie SignInManager.PasswordSignInAsync(...) aufrufen, wirkt sich dies nicht auf die Werte des -Anforderungskontexts aus, da dies keinen Sinn macht -, da der Browser seine Meinung nicht geändert hat, was er vor wenigen Millisekunden gesendet hat. Was dies betrifft, ist der Antwortkontext zum Hinzufügen eines Cookies , das eine Benutzer- und Sitzungs-ID enthält. Dieses Cookie wird dann an den Browser gesendet, der es bei jeder nachfolgenden Anfrage an den Server zurücksendet. Daher werden alle Anforderungen später als diese (bis der Benutzer sich abgemeldet oder der Cookie zu alt ist) Informationen enthalten, die der User.Identity interpretieren kann.

27
Anders Tornblad

Probieren Sie einfach folgendes aus: 

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

Sie könnten in Ihrem Fall andere Daten verwenden, um den gerade angemeldeten Benutzer zu finden. Da wir wissen, dass der Login erfolgreich ist und der Benutzername eindeutig ist, können Sie Folgendes tun:

 //
// 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." });
    }
}
8
Martijn Lentink
HttpContext.User = await _signInManager.CreateUserPrincipalAsync(user);

Nach der Anmeldung können Sie den Anmelde-Manager verwenden, um den Benutzer-Principal zu erstellen und die HttpContext.User-Referenz manuell zuzuweisen

Auf diese Weise können Sie auf die Benutzer-ID wie auf einer normal angemeldeten Seite zugreifen

var userId = userManager.GetUserId(HttpContext.User);
2
Dustin Gamester

Ja, wie Anders sagte, funktionieren User.Identity und User.IsInRole nicht in derselben Login-Aktion .. So müssen Sie zu einer neuen Aktion umleiten, also in Login-Aktion hinzufügen:

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

unten ist ein Codebeispiel:

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

Fügen Sie nun eine neue Aktion LoginRoute wie folgt hinzu:

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

Hoffe das könnte jemandem helfen.

1

Ich lasse den Benutzer direkt nach der Anmeldung folgende Schritte ausführen:

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

Folgendes hat für mich funktioniert:

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

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

Nach der Ausführung erhalten Sie einen authentifizierten Status für die aktuelle Anfrage.

0
Dmitry Duka