前一段在开发一个项目中,需求人员希望能防止同一个用户在同一时间多次登录系统。于是在我们博客园里搜索相关文章,发现解决方案几乎都是千篇一律。见 防止用户多次登录
这种方案个人觉得有两点不足之处:
1、频繁与服务器交互
2、只要用户已登录,就不能再次登录了
我们知道在一台机子上登录QQ后,再到另外一台机子上同样也是可以登录的,不过之前登录的会被 踢掉。我觉得这种方案比较人性化。如果在家里登录QQ后,忘了退出,然后在公司登录时提示“此用户已经登录”,不知你会有何感受?!
解决方法:
1、 用户登录系统时,分配一个GUID给他。如果是用户是首次登录就往Application["OnlineUserList"]中添加一条记录,下次再登录,系统会重新分配一个新GUID,修改已存在的记录值。
2、页面继承基类中,判断客户端保存的cookie["UserOnlineID"] 值是否与服务端一致,如果不一致,则重定向到重复登录页面。
/* 登录用户存入全局Application对象中,
* 如果已存在,则修改系统之前分配的Guid标识
*/
string m_strUserOnlineID = Guid.NewGuid().ToString();
Dictionary<string, string> userlist;
if (Application["OnlineUserList"] == null)
{
userlist = new Dictionary<string, string>();
}
else
{
userlist = Application["OnlineUserList"] as Dictionary<string, string>;
}
if (userlist.ContainsKey(userId))
{
userlist[userId] = m_strUserOnlineID;
}
else
{
userlist.Add(userId, m_strUserOnlineID);
}
Application.Add("OnlineUserList", userlist);
WebGlobal.SetCookie("UserOnlineID", m_strUserOnlineID);
/******** End *******/
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
//对登录用户进行页面访问验证
if (!string.IsNullOrEmpty(HttpContext.Current.User.Identity))
{
/* 获取客户端的用户在线标识Guid
* 如果标识Guid与服务端不一致,则重定向到重复登录页面
*/
string m_strUserOnlineID = WebGlobal.GetCookie("UserOnlineID");
if (!string.IsNullOrEmpty(m_strUserOnlineID))
{
Dictionary<string, string> userlist = Application["OnlineUserList"] as Dictionary<string, string>;
if (m_strUserOnlineID != userlist[HttpContext.Current.User.Identity])
{
Response.Redirect("~/subscribed.shtml");
}
}
/******** End *******/
}
}