成功登录后,会话偶尔会丢失

时间:2020-02-04 00:45:33

标签: c# asp.net authentication session

我的登录网页出现一个奇怪的问题,成功登录后,用户的登录会话偶尔丢失。

用户登录后访问下一页时,由于登录会话不存在,它将被重定向回登录页面。

许多用户中大约10%的时间是随机发生的(似乎如此),通常,经历此操作的同一用户在第二次尝试后就会进入。在我看来,发生这种情况时系统并不忙。

这是登录过程:

  1. 用户在登录页面(login.asp)中输入用户名和密码, 然后从登录页面(login.asp)发送登录凭据 通过javascript到Asp.Net登录处理程序(LoginHandler.ashx) Ajax通话。
  2. 然后,登录处理程序验证凭据并设置登录名 包含用户信息的会话(Session["CC_VendorInfo"])。
  3. 然后,登录处理程序将OK响应发送回Ajax调用。 收到OK响应后,Login.asp上的javascript将 将用户带到下一页。
  4. 当用户请求下一页时,服务器尝试检索信息 在登录会话(Session["CC_VendorInfo"]中)。如果会话为空,则它将 将用户重定向回登录页面。

我在服务器上有一些调试日志,用于打印出登录会话的内容,这证明该会话已在步骤2中成功设置。并且我还有日志显示,在步骤4中,登录会话有时为NULL。

更多说明: 该应用程序已部署在Azure中的标准Windows虚拟机上,因此,由负载平衡引起的会话管理限制似乎不适用于此问题。

此问题的可能原因是什么?任何答案都非常感谢!

Login.asp 中的部分代码:

function Login() {
    $.ajax({
        type: "POST",
        url: "../Home/LoginHandler.ashx",
        data: {
            user: $("#UserName").val(),
            pswd: $("#PassWord").val()
        },
        success: function (response) {
            ProcessLogin(response);
        },
        error: function (xhr, status) {
            alert("Failed to login.");
        }
    })
    return false;
}
function ProcessLogin(response) {
    // ... ...
    if (response == 'OK') {
        window.location.href = strNextUrl;
    } else {
        alert("Failed to login.");
    }
}

LoginHandler.ashx 中的部分代码:

    if (CheckCredential(context, sUserName, sPassword))
    {
        ClsVendorInfo oVendorInfo = new ClsVendorInfo();
        oVendorInfo.iVendorID = iVendorID;
        oVendorInfo.sUserName = sUserName;

        // set the login session here
        ClsCommonUI.SetVendorInfoSession(oVendorInfo);

        sResp = "0|OK";
    }

实用程序类中的一项功能,用于设置登录会话:

    static class ClsCommonUI
    {
        // ... ...

        public static bool SetVendorInfoSession(ClsVendorInfo oVendorInfo)
        {
            ClsVendorInfo oSessVendorInfo = HttpContext.Current.Session["CC_VendorInfo"] as ClsVendorInfo;
            if (oSessVendorInfo != null && 
                (oSessVendorInfo.iVendorID != oVendorInfo.iVendorID || 
                 oSessVendorInfo.iUserID != oVendorInfo.iUserID))
            {
                DebugLog(oSessVendorInfo,
                    string.Format("Login Session Changed [{0}] (before): {1}",
                        HttpContext.Current.Session.SessionID,
                        oSessVendorInfo.Print()));
            }
            // update session
            HttpContext.Current.Session.Remove("CC_VendorInfo"); 
            HttpContext.Current.Session["CC_VendorInfo"] = oVendorInfo.Clone();

            oSessVendorInfo = HttpContext.Current.Session["CC_VendorInfo"] as ClsVendorInfo;

            // I can see the session content being print out in the debug log
            DebugLog(oSessVendorInfo,
                string.Format("SetVendorInfoSession [{0}]: {1}",
                    HttpContext.Current.Session.SessionID,
                    oSessVendorInfo.Print()));

            // ... ...

            return true;
        }

        // ... ...
    }

当用户请求下一页时,这是检查登录会话的代码:

    public static int GetVendorInfo(HttpRequest oReq,
                                    ClsDBAccess oDBAccess,
                                    out ClsVendorInfo oVendorInfo,
                                    [CallerFilePath] string sCallerFileName = "")
    {
        HttpContext context = HttpContext.Current;

        ClsVendorInfo oSessionVendorInfo = context.Session["CC_VendorInfo"] as ClsVendorInfo;

        if (oSessionVendorInfo != null &&
            oSessionVendorInfo.iVendorID != 0)
        {
            // continue processing
            //... ...
        }
        else
        {
            // No Session - go back to login
            RedirectToLogin(HttpContext.Current);
        }
    }

1 个答案:

答案 0 :(得分:0)

如果这不是您的问题,我可以删除此答案。

Chrome对Cookie的新SameSite更改即将删除或已经删除。如果您在Cookie上没有SameSite属性,则chrome会直接删除该Cookie。如果将其设置为“宽松”,则所有跨域iframe都会删除该Cookie。如果此方法在IE中正常运行,则可能是您的问题。如果您使用SameSite = None,则跨域iframe可以运行,但是旧版浏览器也可能会停止运行...