zoukankan      html  css  js  c++  java
  • [laravel]用户异地登录后踢掉之前的登录

    不同用户和服务器之间由一个唯一的session来区分,但是一般情况下不同的session对应的用户model可以是同一个。

    为了实现只能同时在一个地方登陆,可以在用户的字段里增加一个last_session来表示该用户model最近登录使用的session,每当用户进行了一次登陆操作后,把last_session重置为当前的session。然后增加一个中间件,判断每个请求使用的session是否是最近登陆的session,如果不是,返回登录页面,表示你已经被踢了。同时页面上也增加一个定时执行的ajax来判断当前的登录状态是否还有效,如果被踢了,提示并且返回登录页面。

    1)重置last_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函数来自这里:

    而且是一个只有声明(???)没有实现的函数(???)

    看一下它在哪些地方使用过:

    打开第一个文件,找到这个函数:

    注意到下面有个sendLoginResponse函数里面执行了一个session的regenerate,猜测应该是这里产生了一个新的session替换了登录时使用的那个,于是把last_session的重置写在这里:

    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();
                    }
                }
            }
        });
    }
  • 相关阅读:
    366. Find Leaves of Binary Tree输出层数相同的叶子节点
    716. Max Stack实现一个最大stack
    515. Find Largest Value in Each Tree Row查找一行中的最大值
    364. Nested List Weight Sum II 大小反向的括号加权求和
    156. Binary Tree Upside Down反转二叉树
    698. Partition to K Equal Sum Subsets 数组分成和相同的k组
    244. Shortest Word Distance II 实现数组中的最短距离单词
    187. Repeated DNA Sequences重复的DNA子串序列
    java之hibernate之基于主键的双向一对一关联映射
    java之hibernate之基于主键的单向一对一关联映射
  • 原文地址:https://www.cnblogs.com/dramstadt/p/9111718.html
Copyright © 2011-2022 走看看