asp.net mvc 简单实现一个账号只能在一个地方登录
原理:
假设用户在机器A登陆后,
这时用户再次在机器B登陆,会以当前会话的SessionID作为键,用户id作为值,插入dictionary集合中,集合再保存在application(保存在服务器的全局变量,多用户可以共享)变量中,
同时判断集合中是否有其他值,这里A机器已经登陆,所以会有A机器登陆的键值对,将A机器的键对应值修改为“_offline_”,以表示强制下线,
A机器的页面通过js轮询去查询dictionary集合,发现中SessionID键对应的值被修改为“_offline_”,从而注销登陆,并提示被迫下线。
1、global中的代码:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
} //保证同一次会话的SessionID不变
protected void Session_Start(object sender, EventArgs e)
{ } protected void Session_End(object sender, EventArgs e)
{
Hashtable hOnline = (Hashtable)Application["Online"];
if (hOnline != null)
{
if (hOnline[Session.SessionID] != null)
{
hOnline.Remove(Session.SessionID);
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();
}
}
}
}
注:保证同一次会话的SessionID不变,这点很重要 2、用户登陆代码:
..... HttpContext httpContext = System.Web.HttpContext.Current;
var userOnline =
(Dictionary<string,string>)httpContext.Application["Online"];
if (userOnline != null)
{
IDictionaryEnumerator enumerator = userOnline.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Value != null && enumerator.Value.ToString().Equals(userID.ToString()))
{
userOnline[enumerator.Key.ToString()] = "_offline_";
break;
}
}
}
else
{
userOnline = new Hashtable();
}
userOnline[Session.SessionID] = userID.ToString();
httpContext.Application.Lock();
httpContext.Application["Online"] = userOnline;
httpContext.Application.UnLock(); ......
4、页面轮询(可以在母版页,公共页)
前台js用的easyui
$(document).ready(function () {
//定时检测是否被强制下线
setInterval(function () {
CheckIsForcedLogout();
}, 5000);
});
//检测是否被强制下线
function CheckIsForcedLogout() {
$.ajax({
url: "/Home/CheckIsForcedLogout",
type: "POST",
dataType: "json",
success: function (msg) {
if (msg.OperateResult == "Success") {
$.messager.alert('', msg.OperateData, 'error', function () {
window.location.href = "/Account/Login";
});
}
},
error: function (ex) { }
});
}
[HttpPost]
public JsonResult CheckIsForcedLogout()
{
try
{
HttpContext httpContext = System.Web.HttpContext.Current;
Hashtable userOnline = (Hashtable)httpContext.Application["Online"];if (userOnline != null)
{
if (userOnline.ContainsKey(httpContext.Session.SessionID))
{
var value=userOnline[httpContext.Session.SessionID];
//判断当前session保存的值是否为被注销值
if (value != null && "_offline_".Equals(value))
{
//验证被注销则清空session
userOnline.Remove(httpContext.Session.SessionID);
httpContext.Application.Lock();
httpContext.Application["online"] = userOnline;
httpContext.Application.UnLock(); string msg = "下线通知:当前账号另一地点登录, 您被迫下线。若非本人操作,您的登录密码很可能已经泄露,请及时改密。"; //登出,清除cookie
FormsAuthentication.SignOut(); return Json(new { OperateResult = "Success", OperateData = msg }, JsonRequestBehavior.AllowGet);
}
}
}
return Json(new { OperateResult ="Failed" }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(new { OperateResult = "Failed" }, JsonRequestBehavior.AllowGet);
}
}
这里登陆后,每5秒轮询服务器(获取最后登陆时间、ip是从redis缓存读取,所以轮询没有访问数据库),然后不访问数据库,但是数据量大的话,服务器压力也是挺大的,暂时没有更好的解决方案。
asp.net mvc 简单实现一个账号只能在一个地方登录的更多相关文章
- java 实现 一个账号只能在一个地方登陆,其他地方被下线
其实方法有很多的,我这献丑了. 使用理解java 四大作用域. 思路:理解java 四大作用域的关键. 第一个地方登陆: 1.得到请求的SessionId 和 登陆的 用户名 2.把SessionId ...
- Asp.net 实现只能允许一个账号同时只能在一个地方登录
先上帮助类: /// <summary> /// 单点登录帮助类 /// </summary> public class SSOHelper { /// <summary ...
- shiro 实现单用户登录,一个用户同一时刻只能在一个地方登录
我这里 shiro 并没有集成 springMVC,直接使用 ini 配置文件. shiro.ini [main] # Objects and their properties are defined ...
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少. ...
- ASP.NET MVC 5 - 添加一个模型
在本节中,您将添加一些类,这些类用于管理数据库中的电影.这些类是ASP.NET MVC 应用程序中的"模型(Model)". 您将使用.NET Framework 数据访问技术En ...
- ASP.NET MVC 简单介绍①
ASP.NET MVC 简单介绍① 只做了重要描述,内容出自菜鸟教程网站内容. 目录 1布局 2HTML 帮助器 3.Razor 语法 4.添加样式 5.Layout 6. Controllers ...
- ASP.NET MVC 简单分页代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- [转]ASP.NET MVC 5 - 添加一个模型
在本节中,您将添加一些类,这些类用于管理数据库中的电影.这些类是ASP.NET MVC 应用程序中的"模型(Model)". 您将使用.NET Framework 数据访问技术En ...
- Asp.net MVC 简单分页 自做简单分页
Asp.net MVC 简单分页: public static string Pager(int page,int pageSize,int total) { ...
随机推荐
- Java之Servlet
Servlet规范了JavaWeb项目的结构Servlet的规范约束了服务器如何来实现Servlet规范,如何解析JavaWeb项目的结构. Java就是通过接口来约束 Servlet规范的jar就在 ...
- Python 爬虫实例(9)—— 搜索 爬取 淘宝
# coding:utf- import json import redis import time import requests session = requests.session() impo ...
- Windows安装VNC服务端
下载VNC服务端 由于服务器在IDC机房,只能使用系统自带远程桌面连接到服务器进行安装VPC服务端 但在安装过程发现,如果是通过远程桌面连接到服务器进行安装,VNC Mirror Driver会报错无 ...
- 关于XCode工程中PrefixHead.pch文件的使用
1.首先先清除pch文件在工程中的作用: 存放一些全局的宏(整个项目中都用得上的宏) 用来包含一些全部的头文件(整个项目中都用得上的头文件) 能自动打开或者关闭日志输出功能 2.由于新建的XCode工 ...
- Fluent动网格【10】:区域运动案例
本案例主要描述如何在Fluent中处理包含了公转和自转的复合运动.涉及到的内容包括: 多区域模型创建 滑移网格设置 区域运动UDF宏DEFINE_ZONE_MOTION 案例描述 案例几何如图所示. ...
- Unable to find IPv4-only network bridge for LXD.
https://github.com/conjure-up/conjure-up/issues/1440It seems like the the installation is complainin ...
- Android CPU类型及预定义的宏
[时间:2019-02] [状态:Open] [关键词:android,cpu, armeabi, armeabi-v7a, arm64-v8a, 32位,64位,c/c++] 本文主要总结下前段时间 ...
- 【Linux】解决"no member named 'max_align_t'
编译遇到错误: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.1/../../../../include/c++/5.4.1/cstddef:51:11: erro ...
- TF常用知识
命名空间及变量共享 # coding=utf-8 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt; ...
- oracle学习创建和准备Oracle样例数据库
此处有一个Oracle创建数据库和表和插入数据的脚本: http://www.forta.com/books/0672336073/