关于用户表设计及多用户登入限制

1.数据表设计

用户通用信息表

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(32) NOT NULL,
  `avatar` varchar(128) DEFAULT NULL,
  `logintime` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

用户登入信息表

CREATE TABLE `user_auths` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `identity_type` varchar(32) NOT NULL COMMENT '登入类型normal(手机号,邮箱,用户名)或(微信)weixin或(微博)weibo或(QQ)qq',
  `identifier` varchar(56) NOT NULL COMMENT '登入标识(phoneNumber,email,username)或(微信UserName)或(微博UID)',
  `credential` varchar(42) NOT NULL COMMENT '密码凭证access_token',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

2.如何开发

第一步:用户登入成功后刷新授权表(user_autos),并将新生成的密码凭证保存至客户端;

第二步:添加拦截器,除登入请求、退出请求以及静态资源的请求不需要验证外,其他的请求都需要将客户端的密码凭证和服务器的密码凭证进行对比;

第三步:根据匹配结果,如果密码凭证不一致,执行退出操作,并提示该账号已在其他地方登入。

本文用ThinkPHP5.1框架做演示:

用户登入页面Index.php

<?php
namespace app\demo\controller;
class Index extends Com
{
    public function login()
    {
        //测试数据,如果已建库,可以添加至数据表再写入session
        $this->recorder->write('user_id',9527);
        $this->recorder->write('user_name','华安');
        $this->recorder->write('access_token',md5('opassword'));
        $this->success('登入成功','/index/index');
        return '登入首页';
    }
    public function index()
    {
        return '成功登入首页';
    }
}

配置的存储和读取Recorder.php

<?php
namespace app\demo\controller;
use think\facade\Session;
class Recorder
{
    private static $data;
    public function __construct()
    {
        if(!Session::has('user_info')){
            self::$data = array();
        }else{
            self::$data = Session::get('user_info');
        }
    }
    public function write($name,$value)
    {
        self::$data[$name] = $value;
    }
    public function read($name)
    {
        if(empty(self::$data[$name])){
            return null;
        }else{
            return self::$data[$name];
        }
    }
    public function delete($name)
    {
        unset(self::$data[$name]);
    }
    public function __destruct()
    {
        Session::set('user_info',self::$data);
        // TODO: Implement __destruct() method.
    }
}

拦截器Com.php

<?php
namespace app\demo\controller;
use think\App;
use think\Controller;
use think\facade\Session;
class Com extends Controller
{
    protected $recorder;
    public function __construct(App $app = null)
    {
        $this->recorder = new Recorder();
        parent::__construct($app);
    }
    protected function initialize()
    {
        $controller = $this->request->controller();
        $action = $this->request->action();
        //添加拦截器
        if($controller.$action !== 'Indexlogin'){
            //验证是否登录
            if(!$this->check_login()){
                $this->error('请先登录','/index/login',3);
            }
           // $auth = db('user_auths')->where(['user_id'=>$this->recorder->read('user_id')])->find();
           //测试数据,登入方式可以自行选择,这里采用用户名的登入方式
            $auth = ['user_id'=>9527,'identity_type'=>'username','identifier'=>'华安','credential'=>md5('upassword')];
            if(empty($this->recorder->read('access_token'))){
                //token已失效,需要重新登入
                $this->redirect('/index/login');
            }
            if($auth['credential']!==$this->recorder->read('access_token')){
                $this->error('你的账号已在别处登入','/index/login');
            }
        }
    }
    public function check_login()
    {
        $is_login = false;
        if(Session::has('user_info')){
            $is_login = true;
        }
        return $is_login;
    }
}

路由配置route.php

return [
    '__domain__' => [
    'demo' => 'demo',
]

3.小结

本文将用户信息部分和逻辑部分分开处理,方便拓展,适用于多种登入方式。用户信息表可以随时增加任意字段,以满足前端各种业务需求。

注意:请不要将一个账号只能一个人登入这种说法和单点登入混淆开来。

转载于:https://www.cnblogs.com/xizhou/p/10835089.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值