• [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();
                    }
                }
            }
        });
    }
  • 相关阅读:
    Linux启动报错missing operating system
    Linux tmp目录自动清理总结
    ORACLE口令管理
    oom_kill_process造成数据库挂起并出现found dead shared server
    Oracle shutdown immediate遭遇ORA-24324 ORA-24323 ORA-01089
    从flink-example分析flink组件(1)WordCount batch实战及源码分析
    从mysql高可用架构看高可用架构设计
    由mysql分区想到的分表分库的方案
    六边形效果
    迷你MVVM框架 avalonjs1.5.2 发布
  • 原文地址:https://www.cnblogs.com/dramstadt/p/9111718.html
Copyright © 2020-2023  润新知