最近在赶一个项目时用到了单点登录功能,一开始在百度和官网中搜了搜,得到的结果不是不我想要的,毕竟是一个小东西搞的太复杂了。所以自己想出了一个简单实现功能
要求是会员在不同的登录端登录时,退出其它已登录端。开发框架是用的Thinkphp5.1,先前想是直接用缓存实现,后面发现可以用Session和Cache一起更简单实现。
利用的是用户每次登录帐号时,先读取缓存记录单点登录的值并加1,并把此值同时记录到此登录用户信息的Session,在用户公公共类中判断,Session存的值与缓存中的值是否一致,如果不一致则为其它用户登录。则把此用户退出处理,
例如:
用户在谷歌浏览器第一次登录时:用户:ID=1、那么:SinglePoint_1 =1、Session=1,
如果为空那么赋值他为1,
用户在火狐浏览器第二次登录时:用户:ID=1、那么:SinglePoint_1 =2、Session=2,
则谷歌浏览器此时刷新是得到的值 SinglePoint_1=2、Session=1,所以被退出了
login.php (登录页)**********************************************//以下代码只做实例功能演示,省略其它……//获取登录状态$_USER = Session::get('user');//判断是否已登录,如果已是登录状态,则跳转到会员中心主页if ($_USER['id']) {return $this->redirect(url('home'));} //判断POST请求if ($this->request->isPost()) {$user=Db::name('user')->where(['username' => $post['username']])->find();//缓存单点登录值Cache::inc('SinglePoint_'.$user['id']);$user['single_point']=Cache::get('SinglePoint_'.$res['id']);//设置用户信息缓存Session::set('user', $user);//以下进行登录成功所跳转,等操作略过//}else{return $this->fetch();}
common.php(这是一个公共类页面,会员登录成功后,会员页面的其它功能都继承着这个公共类)//以下代码只做实例功能演示,省略其它……//这里用到了控制器初始化,这是thinkphp主自定义的,其实和php中构造方法 __construct()其实是一样的, protected static $_UID = null;public function initialize() {//获取登录状态$_USER = Session::get('user');//判断是否已登录,否则跳到登录页if ($_USER['id']) {$single_point=Cache::get('SinglePoint_'.$_USER['id']);if(empty($single_point) || $_USER['single_point']!=$single_point){return $this->logout();}self::$_UID = $_USER['id']; //用户ID}else{return $this->redirect(url('login'));}}/*** Notes: 退出登录*/public function logout() {if(self::$_UID){Cache::rm('SinglePoint_'.self::$_UID);}Session::delete('user');$this->redirect(url('login'));}