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

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

问题描述

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

I've defined a temp variable to get current user id, it always returns 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." });
        }
    }

更新 2:

在客户端,我使用ajax连接到/Account/Login:

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:

SignalR on client side:

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

服务器端的SignalR:

SignalR on server side:

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

推荐答案

实际上,用户登录 - 不在当前请求的上下文 (POST/Account/Login 请求),这是 User.Identity 获取其数据的地方.如果您想提取当前尝试 (并且显然成功) 登录的用户的 id,您需要以其他方式执行此操作,例如劫持对 的调用中的某个步骤SignInManager.PasswordSignInAsync.如果您要实现自己的 MembershipProvider,这应该很容易.

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.

否则,您将不得不等待下一个请求(由某些控制器的 Action 方法处理的任何请求都可以)使用User.Identity 以您想要的方式.

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.

当您的 Login 方法被调用时,请求上下文已经被评估并且大量数据可用.例如 HTTP 标头、cookie 等.在这里可以找到所有上下文信息,例如 User.Identity.

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.

当您调用 SignInManager.PasswordSignInAsync(...) 时,这不会影响请求上下文的值,因为这会毫无意义——因为浏览器并没有改变它几毫秒前发送的内容的想法.它确实影响的是响应上下文添加一个包含一些用户和会话ID的cookie.然后将此 cookie 发送到浏览器,然后浏览器将其发送回服务器以用于每个后续请求.因此,在此之后的所有请求(直到用户退出或 cookie 变旧) 都将包含供 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天全站免登陆