2015-11-27 5 views
23

Ich habe eine temporäre Variable definiert, um die aktuelle Benutzer-ID abzurufen. Sie gibt immer null zurück. HierUser.Identity.GetUserId() gibt nach erfolgreicher Anmeldung null zurück.

ist der Schnappschuss:

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 Client-Seite, verwende ich AJAX /Account/Login verbinden:

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 Client-Seite:

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

SignalR auf Server-Seite:

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

Code als Text anzeigen Bitte, nicht als Bild. –

Antwort

23

Eigentlich ist der Benutzer nicht angemeldet - nicht im Rahmen der die aktuelle Anforderung(die POST /Account/Login Anfrage), die ist, wo User.Identity bekommt seine Daten. Wenn Sie die ID des Benutzers, der gerade versucht, (und scheinbar erfolgreich) zu versuchen, um sich anzumelden, müssen Sie das auf eine andere Weise tun, wie Hijacking einige Schritt innerhalb des Aufrufs an SignInManager.PasswordSignInAsync. Wenn Sie Ihre eigene MembershipProvider implementieren, sollte dies einfach sein.

Andernfalls werden Sie für die nächste Anfrage(jede Anforderung, indem er einige Kontrolleurs Aktion Methode behandelt sollte gut tun) warten müssenUser.Identity in der Art und Weise zu verwenden, die Sie wollen.

Einige hinzugefügt Erklärung

Wenn Ihr Login Methode aufgerufen wird, wird die Anforderung Kontext bereits ausgewertet und eine Menge von Daten zur Verfügung steht. Zum Beispiel HTTP-Header, Cookies und so weiter. Hier finden Sie alle Kontextinformationen, z. B. User.Identity.

Wenn Sie SignInManager.PasswordSignInAsync(...) nennen, tut dies nicht die Werte des Anforderungskontext beeinflussen, weil dies keinen Sinn machen würde - da der Browser seine Meinung nicht geändert hat, was es vor wenigen Millisekunden gesendet. Was es betrifft, ist der Antwortkontext, um einen Cookie hinzuzufügen, der irgendeine Benutzer- und Sitzungsidentifikation enthält. Dieser Cookie wird dann an den Browser gesendet, der ihn für jede weitere Anfrage an den Server zurücksendet. Also alle Anfragen später als diese (bis der Benutzer abmeldet oder der Cookie zu alt wird) enthält Informationen für die User.Identity zu interpretieren.

+0

Danke! Kannst du mir mehr über "die aktuelle Anfrage" und "die nächste Anfrage" erklären? Wann wird eine Anfrage "aktuelle Anfrage" oder "nächste Anfrage" genannt? –

+0

Nun, das ist nur Grund Englisch und Zeitlichkeit. Die "aktuelle" Anfrage ist die HTTP-Anfrage, die Ihr Code * zur Zeit bearbeitet * - in diesem Fall ist es die Anfrage "POST/Account/Login". Bei der "nächsten" Anfrage meine ich einfach die nächste Anfrage zu einem späteren Zeitpunkt * (von Mikrosekunden später bis zu Tagen später) * ... –

+0

ya. Ich denke etwas stimmt nicht. Ich gebe Ihnen ein Beispiel: Auf der Client-Seite verwende ich Ajax, um mit '/ Account/Login' zu verbinden. Nach erfolgreicher Anmeldung benutze ich erneut ajax, um den signalR Hub ('/ Hubs/ChatHub.cs') zu verbinden. Ich habe eine Methode definiert, um userId zu erhalten, aber sie ist immer noch null. 'public void SigninToSignalR() {Zeichenfolge userId = HttpContext.Current.User.Identity.GetUserId(); } ' –

1

Ja, wie Anders sagte, User.Identity und User.IsInRole funktionieren nicht innerhalb derselben Login-Aktion. Also, Sie müssen auf eine neue Aktion umleiten, also in Login-Aktion hinzufügen:

zurück RedirectToAction ("MyNewLoginRoute", neue {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 }); 

Und nun, wie unten eine neue Aktion LoginRoute hinzufügen:

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

Hope this jemand helfen könnte.

7

Sie könnten in Ihrem Fall andere Daten verwenden, um den Benutzer zu finden, der sich gerade angemeldet hat. Da wir wissen, dass die Anmeldung erfolgreich ist und der Benutzername eindeutig ist, wird Folgendes funktionieren;

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

Ganz einfach versuchen:

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

Danke Mann, endlich ein einfacher. –

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

Nachdem Sie die Unterzeichnung der Zeichen in Manager verwenden, um den Benutzer Principal zu erstellen und manuell die HttpContext.User Referenz

Dies wird vergeben Dann können Sie auf die Benutzer-ID zugreifen, als würden Sie mit einer normalen Seite

var userId = userManager.GetUserId(HttpContext.User); 
01 auf die Benutzer-ID zugreifen
0

Ich erhalte der Benutzer das folgende Recht nach der Anmeldung dabei:

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