不一样用户和服务器之间由一个惟一的session来区分,可是通常状况下不一样的session对应的用户model能够是同一个。ajax
为了实现只能同时在一个地方登录,能够在用户的字段里增长一个last_session来表示该用户model最近登陆使用的session,每当用户进行了一次登录操做后,把last_session重置为当前的session。而后增长一个中间件,判断每一个请求使用的session是不是最近登录的session,若是不是,返回登陆页面,表示你已经被踢了。同时页面上也增长一个定时执行的ajax来判断当前的登陆状态是否还有效,若是被踢了,提示而且返回登陆页面。json
1)重置last_session服务器
这是登陆时用的函数:session
protected function attemptLogin(Request $request) { if ($this->guard()->attempt($this->credentials($request), $request->has('remember'))){ return $this->guard()->attempt($this->credentials($request), $request->has('remember')); } }
登陆的函数在LoginController里,可是在这个函数里重置last_session是没用的。函数
return时调用的attempt函数来自这里:this
并且是一个只有声明(???)没有实现的函数(???)url
看一下它在哪些地方使用过:spa
打开第一个文件,找到这个函数:3d
注意到下面有个sendLoginResponse函数里面执行了一个session的regenerate,猜想应该是这里产生了一个新的session替换了登陆时使用的那个,因而把last_session的重置写在这里:code
Auth::user()->last_session=Session::getId();
Auth::user()->save();
成功了。
2)中间件
public function handle($request, Closure $next){ if (Session::getId()!=Auth::user()->last_session){ if ($request->ajax())return response()->json(['status'=>'guoqile']); else return redirect('login'); } return $next($request); }
3)页面ajax(和一个读取新消息的混在一块儿了)
$(document).ready(function(){ setInterval("ajaxGetNotify()", 5000) }); //$(document).ready(ajaxGetNotify()); var title = document.title function ajaxGetNotify(){ $.ajax({ type: 'GET', url: 'notification_num', dataType: 'json', success: function(data){ var i=0; if (data['num'] != undefined) { if (data['num'] > 0) { setInterval(function test() { i++; if (i == 1) document.title = '【新消息】' + title; if (i == 2) document.title = '【 】' + title; if (i == 3) i = 0; }, 600); } } if (data['status'] != undefined) { if (data['status'] == 'guoqile') { alert('因为帐号在另外一地点登陆,您已被迫下线。'); location.reload(); } } } }); }