【问题标题】:Global OnLoggedOut event in ASP.net?ASP.net 中的全局 OnLoggedOut 事件?
【发布时间】:2012-06-15 17:57:54
【问题描述】:

当用户从 ASP.net 网站注销时,是否有办法得到通知?

注意:用户可以在不访问或单击“注销”链接的情况下退出。

当用户注销时,我想清除一些与会话相关的信息,并写入数据库。

注意:LoginStatus.OnLoggedOut 事件。问题是该控件并不存在于每个页面上,用户也不必使用LoginStatus 控件来注销(例如,当登录超时或用户注销时)

与 Global.asax 具有全局 On Session Stop 通知的方式相同:

void Session_End(object sender, EventArgs e) 
{
}

我假设某处有一个 On User Logged Out 通知:

void LoggedOut(object sender, EventArgs e)
{
}

阅读奖励

【问题讨论】:

  • 我使用了 LoginStatus.OnLoggedOut 事件

标签: asp.net forms-authentication stay-logged-in


【解决方案1】:

我不同意。有时您想知道用户何时注销。例如,我有一个应用程序需要扫描所有登录用户,以查看管理级别是否有“任何人在家”。有时经理可能正在浏览网站但实际上并未登录。他们的会话可能仍处于活动状态,因为经理最近已注销但仍在浏览网站,而软件需要知道这一点。

在这种情况下,我已经制作了HttpRuntime.Cache逻辑来捕获登录事件和数据,包括用户名和IP地址,用户名等。这个方法被调用:

public static void Application_AuthenticateRequest(object sender, EventArgs e)

然后我使用该数据执行逻辑计算登录状态和其他有用的应用程序详细信息。

以下内容快速且未经测试,但如果您提出此类问题,我相信您可以清理它:)。希望对你有帮助。

 public static void HandleUserLoginLogic()
    {
        string UserName = HttpContext.Current.User.Identity.Name.ToString();
        if (UserName != null)
        {
            // if the user has logged in but we have not performed logic, do it now
            if (HttpRuntime.Cache["Authenticated_" + UserName] == null)
            {
                // absolutely confirm the user has logged in
                if (UsrMan.IsUserLoggedIn())
                {
                    // SETUP MY RUNTIME VARIABLES NOW
                    HttpRuntime.Cache["AuthenticatedIPAddress_" + System.Web.HttpContext.Current.Request.UserHostAddress] = UserName;
                    HttpRuntime.Cache["Authenticated_" + UserName] = true;
                    String[] roles = UsrMan.GetRolesForUser(UserName);
                    // handle roles for this user for future application uses in the future.
                    foreach (string role in roles)
                    {
                        // handle first time condition
                        if (HttpRuntime.Cache["AuthenticatedUserInRole_" + role] != null)
                        {
                            StringCollection scUserRole = (StringCollection)HttpRuntime.Cache["AuthenticatedUserInRole_" + role];
                            if (!scUserRole.Contains(UserName))
                            {
                                scUserRole.Add(UserName);
                                HttpRuntime.Cache["AuthenticatedUserInRole_" + role] = scUserRole;
                            }
                        }
                        // handle standard condition
                        else
                        {
                            StringCollection scUserRole = new StringCollection();
                            scUserRole.Add(UserName);
                            HttpRuntime.Cache["AuthenticatedUserInRole_" + role] = scUserRole;
                        }
                    }
                }
            }
        }

        // HANDLE LOGGED OUT CONDITION
        if ((HttpRuntime.Cache["AuthenticatedIPAddress_" + System.Web.HttpContext.Current.Request.UserHostAddress] != null) && (UserName == null))
        {
            string OldUserName = HttpRuntime.Cache["AuthenticatedIPAddress_" + System.Web.HttpContext.Current.Request.UserHostAddress].ToString();
            HttpRuntime.Cache["Authenticated_" + OldUserName] = null;
            String[] roles = UsrMan.GetRolesForUser(UserName);
            foreach (string role in roles)
            {
                StringCollection scUserRole = (StringCollection)HttpRuntime.Cache["AuthenticatedUserInRole_" + role];
                scUserRole.Remove(UserName);
                if (scUserRole.Count > 0)
                    HttpRuntime.Cache["AuthenticatedUserInRole_" + role] = scUserRole;
                else
                    HttpRuntime.Cache["AuthenticatedUserInRole_" + role] = null;
            }
        }
    }
    public static bool IsUserLoggedIn()
    {
        bool result = false;
        if (HttpContext.Current.User != null &&
      HttpContext.Current.User.Identity != null
          && HttpContext.Current.User.Identity.IsAuthenticated)
        { result = true; }
        return result;
    }

【讨论】:

  • 正是我要找的东西......太糟糕了,我不是 OP,无法向您发送已回答的复选标记:P
【解决方案2】:

网站的一个基本问题是,如果用户关闭浏览器,网站永远不会知道。其含义指向更好的解决方案。您必须重新考虑“登录” 到网站意味着什么。

您通常不需要知道用户何时“退出”我们的网站,因为没有“登录”。每次用户访问页面时,网络服务器验证他们是谁;是否通过:

  • NTML
  • Kerberos
  • HttpAuth
  • 会话 cookie
  • 持久性 cookie
  • 其他一些机制(例如您的 IPv6 地址)

用户“登录” 每次页面加载。浏览器获取页面后,用户不再存在(就网络服务器而言)。这意味着用户在获取页面后“退出”

但是登录很慢

进行特殊登录事件的通常原因是您可以缓存用户的信息(例如姓名、权限)。与其每次刷新页面时都必须进行昂贵的数据库获取,为什么不从缓存中获取呢?但是,作为一名优秀的开发人员,我们还需要在不再需要该信息时使其过期。但由于无法知道用户何时“完成” 使用您的网站,因此无法知道何时刷新缓存信息。

所以不要缓存它。

SQL Server 有一套非常先进的数据缓存机制;再次查询数据即可。

另一种可能是将数据存储在用户的Session 中。这是完全有效的;信息将保留在那里,直到会话结束。但是很多人反对将数据存储在Session 中,因为这会占用内存。他们主张将其存储在像 SQL Server 这样的数据库中。这又回到了:只需在 SQL Server 中再次查询

如果获取信息昂贵或耗时,那么您可以缓存它 - 但使用设计为缓存的缓存:

Page.Cache

这是

的别名
Page.Application.Cache

【讨论】:

    【解决方案3】:

    在实际注销用户时实现逻辑是否重要?或者,如果你让它更全局处理,创建一个事件并订阅它,这样它将是事件驱动的......

    【讨论】:

    • 如果我错过了一个位置,或者不了解用户可以注销的每个位置(会话结束时?会话超时?应用程序池回收时),这只是一件大事? 当他们 50 年的持久性 cookie 到期时?)
    • @IanBoyd,你确定你在这里尝试做正确的事吗?你想收集什么信息?
    • 您是否在用户注销时尝试登录?我不确定这是否可能非常可靠。如果我对保留用户活动日志的看法是正确的,您能否改为保留会话日志?
    猜你喜欢
    • 2012-06-15
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2010-10-30
    • 2016-07-16
    相关资源
    最近更新 更多