成功登录后,User.Identity.GetUserId()返回null

Tân*_*Tân 36 c# asp.net-mvc identity asp.net-mvc-5

我已经定义了一个临时变量来获取当前用户ID,它总是返回null.

这是快照:

用户身份

为什么?

更新:

    //
    // 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." });
        }
    }
Run Code Online (Sandbox Code Playgroud)

更新2:

在客户端,我使用ajax连接到/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 ma?y chu?.')
            }
        });
        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
            }
        });
Run Code Online (Sandbox Code Playgroud)

客户端SignalR:

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

服务器端的SignalR:

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

And*_*lad 28

实际上,用户没有登录 - 不在当前请求 (POST /Account/Login请求)的上下文中,这是User.Identity获取其数据的位置.如果你想提取当前正在尝试(并且显然是成功)登录的用户的id ,你需要以其他方式这样做,比如在调用中劫持一些步骤SignInManager.PasswordSignInAsync.如果您正在实施自己的MembershipProvider,这应该很容易.

否则,您将不得不等待下一个请求 (某些Controller的Action方法处理的任何请求应该没问题)User.Identity您想要的方式使用.

一些补充说明

当你的Login方法被调用,请求上下文已经评估和大量的数据是可用的.例如HTTP标头,cookie等.这是找到所有上下文信息的地方,比如User.Identity.

当你调用SignInManager.PasswordSignInAsync(...),这并不会影响值的要求范围内,因为这将毫无意义-因为浏览器并没有改变其主意是什么发出的几毫秒前.它影响的是添加包含一些用户和会话ID 的cookie响应上下文.然后将此cookie发送到浏览器,然后浏览器将每个连续请求发送回服务器.因此,所有晚于此的请求(直到用户退出或cookie变得过旧)将包含要解释的信息.User.Identity

  • 这就是退出后需要进行重定向的相同原因;注销将在构造HTTP上下文之后发生,并且如果您发出注销,则只有下一个请求实际上将处于注销上下文中。 (2认同)

Bee*_*ees 28

试试这个:

string userId = SignInManager
.AuthenticationManager
.AuthenticationResponseGrant.Identity.GetUserId();
Run Code Online (Sandbox Code Playgroud)


小智 9

在您的情况下,您可以使用其他数据来查找刚刚登录的用户.由于我们知道登录成功且用户名是唯一的,因此以下内容将起作用;

 //
// 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." });
    }
}
Run Code Online (Sandbox Code Playgroud)


Dus*_*ter 5

HttpContext.User = await _signInManager.CreateUserPrincipalAsync(user);
Run Code Online (Sandbox Code Playgroud)

登录后,您可以使用登录管理器创建用户主体并手动分配 HttpContext.User 引用

然后,您将可以像使用普通登录页面一样访问用户 ID

var userId = userManager.GetUserId(HttpContext.User);
Run Code Online (Sandbox Code Playgroud)