User.Identity.GetUserId()成功登录后返回null [英] User.Identity.GetUserId() returns null after successful login

查看:1606
本文介绍了User.Identity.GetUserId()成功登录后返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



下面的快照:





为什么



更新:

  // 
// POST:/帐号/登录
[HttpPost]
[使用AllowAnonymous]
公共异步任务<&的ActionResult GT;登录(LoginViewModel型号,串RETURNURL)
{
如果(!ModelState.IsValid)
{
返回JSON(新{成功=假,前=无法登录。 });
}

VAR的结果=等待SignInManager.PasswordSignInAsync(model.Email,model.Password,isPersistent:真,shouldLockout:假);
开关(结果)
{
情况下SignInStatus.Success:
字符串userid = User.Identity.GetUserId();
返回JSON(新{成功=真});
情况下SignInStatus.Failure:
返回JSON(新{成功=假,恩=电子邮件或密码不正确});
默认:
返回JSON(新{成功=假,前=无法登录。});
}
}



更新2:



在客户端,我用ajax连接到 /帐号/登录

  VAR loginAjax =功能(电子邮件,密码,回调){
$阿贾克斯({
网址:'/帐号/登录',
型:POST,
数据:{电子邮件:电子邮件,密码:password},
成功:功能(数据){
$('身体')的CSS(。 光标','默认');
如果(data.success){
回调(真)
}其他{
$('#登录错误)文本(data.ex)
}
},
错误:函数(){
$('#登录错误)文本(康元的KET NOIđến可能楚。 。')
}
});
回调(假)
};


//我有电子邮件地址和密码在另一个函数来检查有效与否
loginAjax(电子邮件,密码功能(成功){
$( 身体),CSS('光标','默认');
开关(成功){
情况属实:
登入(函数(){
$('。登录)HTML('');
window.location.href ='/类型=推广?';
});
突破
案假:
$('#电子邮件主动')隐藏();
$('#密码主动)隐藏();
$('#密码)VAL('')。 ;
$('#登录-BTN')removeClass移除(禁用)ATTR('的onclick','$(本).addClass(禁用)removeAttr(的onclick);。运行( )');
突破
}
});



SignalR在客户端:

  VAR signalR = $ .connection.chat; 
VAR登入=函数(回调){
$ .connection.hub.start()来实现(函数(){
signalR.server.signinToSignalR();
回调( )
})
};



SignalR服务器端:

 公共无效SigninToSignalR()
{
//这个总是空
字符串userid = HttpContext.Current.User.Identity.GetUserId();
}


解决方案

其实,用户是< STRONG>不可以签署了 - 不是的背景下的当前请求 (即 POST /帐号/登录要求) 的,这是在 User.Identity 获取数据。如果你想提取用户的id目前正在努力的(显然成功)的登录,你需要做的是,在一些其他的方式,比如劫持电话里面的一些步骤,以 SignInManager.PasswordSignInAsync 。如果要实现自己的的MembershipProvider ,这应该很容易。



否则,你将不得不等待< STRONG>下一个请求 (某些控制器的操作方法处理的任何请求应该做的罚款)的使用 User.Identity 在路上你想。



一些额外的解释



当你的登录方法被调用,请求上下文已经评估,大量的数据是可用的。例如HTTP头,饼干等。这是所有的上下文信息被发现,如 User.Identity



当你调用 SignInManager.PasswordSignInAsync(...),这样做的不可以影响的请求上下文的值,因为这将毫无意义 - 因为浏览器并没有改变主意,它发出的几毫秒前。它所做的是影响在响应上下文添加饼干包含一些用户和会话ID。然后,该cookie被发送到浏览器,然后将其发送回服务器对于每个连续请求。因此,所有的要求比这一个的之后(直到用户退出或饼干变得太老)的将包括信息 User.Identity 解释


I've defined a temp variable to get current user id, it always returns null.

Here is the snapshot:

Why?

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:

On client side, I use ajax to connect to /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 on client side:

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

SignalR on server side:

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

解决方案

Actually, the user is not signed in - not in the context of the current request (the POST /Account/Login request), which is where User.Identity gets its data. If you want to extract the id of the user currently trying to (and apparently succeeding) to sign in, you need to do that in some other way, like hijacking some step inside the call to SignInManager.PasswordSignInAsync. If you are implementing your own MembershipProvider, this should be easy.

Otherwise, you will have to wait for the next request (any request handled by some Controller's Action method should do fine) to use User.Identity in the way you want to.

Some added explanation

When your Login method gets called, the request context is already evaluated and a lot of data is available. For example HTTP headers, cookies and so on. This is where all the context information is found, like User.Identity.

When you call SignInManager.PasswordSignInAsync(...), this does not affect the values of the request context, because this would make no sense – since the browser has not changed its mind about what it sent a few milliseconds ago. What it does affect is the response context to add a cookie containing some user and session id. This cookie is then sent to the browser, which then sends it back to server for each successive request. So all requests later than this one (until the user signs out or the cookie gets too old) will include information for the User.Identity to interpret.

这篇关于User.Identity.GetUserId()成功登录后返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆