tp5 auth 权限详解

浏览1133

角色权限,我们做任何网站几乎都是需要的,以下是一个简单的案例,大家可以参考下:

思路:

1、创建三张表。

管理员表,角色表(用于记录权限角色值),导航表(用于导航添加及遍历)

2、登录成功之后, session 记录角色 groud_id ;

通过 groud_id 查询 groud 角色表  并session记录该角色权限值

3、公共控制器中用 mysql “ in“函数, 查询角色表,并匹对角色值,有权限的栏目就在导航中显示。


一、tp5权限功能,效果图:

管理员列表:

1.jpg

管理员添加功能:

image.png

角色表:

2.jpg

角色添加:

image.png

二、创建数据表:

1、管理员表:

CREATE TABLE `tp5_admin` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(10) DEFAULT NULL COMMENT '账号',
  `realname` varchar(10) DEFAULT NULL COMMENT '真实姓名',
  `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  `password` varchar(35) DEFAULT NULL COMMENT '密码',
  `img` varchar(255) DEFAULT NULL COMMENT '头像',
  `addtime` varchar(11) DEFAULT NULL COMMENT '添加时间',
  `updatetime` varchar(11) DEFAULT NULL COMMENT '修改时间',
  `stop` int(2) DEFAULT '1' COMMENT '是/否启用(1启用,0不启用)',
  `login_num` int(11) DEFAULT '0' COMMENT '登录次数',
  `group_id` int(11) DEFAULT NULL COMMENT '权限组',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2、导航表:

CREATE TABLE `tp5_nav` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL COMMENT '栏目名称',
  `ac` varchar(255) DEFAULT NULL COMMENT '栏目方法',
  `co` varchar(255) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL COMMENT '栏目地址',
  `sort` int(11) DEFAULT '0' COMMENT '排序',
  `stop` int(2) DEFAULT '0' COMMENT '是/否启用',
  `pid` int(11) DEFAULT NULL COMMENT '父id',
  `type` int(11) DEFAULT NULL COMMENT '栏目类型',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

3、权限表:用于记录拥有的权限

CREATE TABLE `tp5_group` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL COMMENT '管理员级别',
  `desc` varchar(255) DEFAULT NULL COMMENT '管理员描述',
  `rule` varchar(255) DEFAULT NULL COMMENT '拥有权限',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

三、实现代码:

业务逻辑代码

1、管理员列表

<div class="row">
	<div class="col-xs-12 col-md-12">
		<div class="widget">
			<div class="widget-header ">
				<span class="widget-caption">管理员管理</span>
				<div class="widget-buttons">
					<a href="#" data-toggle="maximize">
						<i class="fa fa-expand"></i>
					</a>
					<a href="#" data-toggle="collapse">
						<i class="fa fa-minus"></i>
					</a>
				</div>
			</div>
			<div class="widget-body">
				<div class="table-toolbar">
					<a id="editabledatatable_new" href="{:url('admin/Sys/magadd')}" class="btn btn-primary">
						+添加管理员
					</a>
				</div> 
				<table class="table table-striped table-hover table-bordered" id="editabledatatable">
					<thead>
						<tr role="row">
							<th>
								ID
							</th>
							<th>
								账号
							</th>
							<th>
								真实姓名
							</th>
							<th>
								角色
							</th>
							<th>
								邮箱
							</th>
							<th>
								头像
							</th>
							<th>
								登录次数
							</th>
							<th>
								添加时间
							</th>
							<th>
								最近修改
							</th>
							<th>
								状态
							</th>
							<th width="13%">
								操作
							</th>
						</tr>
					</thead>

					<tbody>
					{volist name="maglist" id="vo"}
						<tr>
							<td>{$vo.id}</td>
							<td>{$vo.username}</td>
							<td>{$vo.realname}</td>
							<td class="center ">{$vo.name}</td>
							<td class="center ">{$vo.email}</td>
							<td class="center "><img src="{$vo.img}" alt="" width="50px;" height="50px;"></td>
							<td class="center ">{$vo.login_num}</td>
							<td class="center ">{$vo['addtime']|date='Y-m-d H:i:s',###}</td>
							<td class="center ">{$vo['updatetime']|date='Y-m-d H:i:s',###}</td>
							<td class="center ">
								<label class="qd_btn_{$vo.id}">
									{if condition="$vo.stop eq null"}
                                    <input class="checkbox-slider slider-icon colored-success" type="checkbox" onclick="qdswt(this,{$vo.id});">
                                    <span class="text"></span>
                                    {else/}
                                    <input class="checkbox-slider slider-icon colored-success" type="checkbox" checked="checkbox" onclick="reset_qdswt(this,{$vo.id});">
                                    <span class="text"></span>
                                    {/if}
                                </label>
							</td>
							<td>
								<a href="{:url('admin/Sys/magedit',array('id'=>$vo.id))}" class="btn btn-info btn-xs edit"><i class="fa fa-edit"></i> 编辑</a>
								<a href="{:url('admin/Sys/magedel',array('id'=>$vo.id))}" onclick="return confirm('你确定要删除该管理员么?');" class="btn btn-danger btn-xs delete"><i class="fa fa-trash-o"></i> 删除</a>
							</td>
						</tr>
					{/volist}
					</tbody>
				</table>
				<div style="clear:both"></div>
				<div class="row" style="margin-top:1%;">
					<div class="col-md-12">
						<ul class="pagination pull-right">
							{$maglist->render()}
						</ul>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

PHP代码:

// 管理列表
    public function maglist()
    {
      // $maglist=db('admin')->order('id desc')->paginate(10);
      $maglist = \think\Db::name('admin')->alias('a')->join('group b','a.group_id=b.id')->field('a.*,b.name')->order('id desc')->paginate(10);
      $this->assign('maglist',$maglist);
      return $this->fetch();
    }

2、管理员添加:

<div class="row">
	<div class="col-lg-12 col-sm-12 col-xs-12">
	    <div class="widget">
	        <div class="widget-header bordered-bottom bordered-themeprimary">
	            <span class="widget-caption">管理添加</span>
	        </div>
	        <div class="widget-body">
	            <div>
	                <form class="form-horizontal form-bordered" role="form" enctype="multipart/form-data" method="post" action="">
                        <div class="form-group">
                            <label for="inputusername" class="col-sm-2 control-label no-padding-right">账号</label>
                            <div class="col-sm-4">
                                <input type="text" class="form-control" id="inputusername" placeholder="账号" name="username">
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputPassword" class="col-sm-2 control-label no-padding-right">密码</label>
                            <div class="col-sm-4">
                                <input type="text" class="form-control" id="inputPassword" placeholder="密码" name="password">
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputrealname" class="col-sm-2 control-label no-padding-right">真实姓名</label>
                            <div class="col-sm-4">
                                <input type="text" class="form-control" id="inputrealname" placeholder="真实姓名" name="realname">
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputemail" class="col-sm-2 control-label no-padding-right">邮箱</label>
                            <div class="col-sm-4">
                                <input type="email" class="form-control" id="inputemail" placeholder="邮箱" name="email">
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="inputgroup" class="col-sm-2 control-label no-padding-right">角色</label>
                            <div class="col-sm-4">
                               <select data-toggle="simplecolorpicker" name="group_id">
                                   {volist name="grouplist" id="vo"}
	                                    <option value="{$vo.id}">{$vo.name}</option> 
	                                {/volist}
                               </select>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputgroup" class="col-sm-2 control-label no-padding-right">头像</label>
                            <div class="col-sm-4">
                               <input type="file" name="img" id="doc" multiple="multiple" onchange="javascript:setImagePreview();" class="btn btn-primary">
                            </div>
                        </div>
                        <div class="form-group uplabel" style="display:none">
                        	<label for="inputgroup" class="col-sm-2 control-label no-padding-right">预览</label>
                            <div class="col-sm-4" id="localImag">
                                    <img class="editable img-responsive editable-click editable-empty" id="preview" src="" style="display: block;" />
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-sm-offset-2 col-sm-10">
                                <button type="submit" class="btn btn-primary">添加</button>
                            </div>
                        </div>
                    </form>
	            </div>
	        </div>
	    </div>
	</div>
</div>

PHP代码:

    public function magadd(){
            $username=input('username');
            $maglist=\think\Db::name('admin')->where(array('username' =>$username))->find();
            // 角色列表
            $group_list=db('group')->order('id asc')->select();
            $this->assign('group_list',$group_list);
            if(request()->isPost()){
              // halt(input());
                $data=[
                    'username'=>input('username'),
                    'password'=>md5(input('password')),
                    'realname'=>input('realname'),
                    'email'=>input('email'),
                    'group_id'=>input('group_id'),
                    'addtime'=>time(),
                    'updatetime'=>time(),
                ]; 
                $validate = \think\Loader::validate('Mag');
                if($validate->check($data)){
                        if($_FILES['img']['tmp_name']){
                        // 获取表单上传文件 例如上传了001.jpg
                        $file = request()->file('img');
                        // 移动到框架应用根目录/public/uploads/ 目录下
                        $info = $file->move(ROOT_PATH . 'public' . DS . '/static/uploads/mag');
                        if($info){
                            // 成功上传后 获取上传信息
                            // 输出 jpg
                            $data['img']='/public/static/uploads/mag/'.date('Ymd').'/'.$info->getFilename();
                        }else{
                            // 上传失败获取错误信息
                            echo $file->getError();
                        }
                    }
                $res=\think\Db::name('admin')->insert($data);
                if($res){
                  return $this->success('添加成功!','maglist');
                }
                else{
                  return $this->error('添加失败');
                }
              }else{
                return $this->error($validate->getError());
              }
              return;
      }
        $grouplist=\think\Db::name('group')->select();
        $this->assign('grouplist',$grouplist);
         return $this->fetch();
    }

3、角色权限列表:

<div class="row">
	<div class="col-xs-12 col-md-12">
		<div class="widget">
			<div class="widget-header ">
				<span class="widget-caption">角色权限</span>
				<div class="widget-buttons">
					<a href="#" data-toggle="maximize">
						<i class="fa fa-expand"></i>
					</a>
					<a href="#" data-toggle="collapse">
						<i class="fa fa-minus"></i>
					</a>
				</div>
			</div>
			<div class="widget-body">
				<div class="table-toolbar">
					<a id="editabledatatable_new" href="{:url('admin/Sys/groupadd')}" class="btn btn-primary">
						+添加角色
					</a>
				</div> 
				<table class="table table-striped table-hover table-bordered" id="editabledatatable">
					<thead>
						<tr role="row">
							<th>
								ID
							</th>
							<th>
								角色
							</th>
							<th>
								备注
							</th>
							<th width="60%">
								拥有权限
							</th>
							<th width="13%">
								操作
							</th>
						</tr>
					</thead>

					<tbody>
					{volist name="grouplist" id="vo"}
						<tr>
							<td>{$vo.id}</td>
							<td>{$vo.name}</td>
							<td>{$vo.desc}</td>
							<td>{$vo.rule}</td>
							<td>
								<a href="{:url('admin/Sys/groupedit',array('id'=>$vo.id))}" class="btn btn-info btn-xs edit"><i class="fa fa-edit"></i> 编辑</a>
								<a href="{:url('admin/Sys/groupdel',array('id'=>$vo.id))}" onclick="return confirm('你确定要删除该管理员么?');" class="btn btn-danger btn-xs delete"><i class="fa fa-trash-o"></i> 删除</a>
							</td>
						</tr>
					{/volist}
					</tbody>
				</table>
			</div>
		</div>
	</div>
</div>

PHP 代码:

    // 角色列表
	public function grouplist(){
      $grouplist = \think\Db::name('group')->order('id desc')->select();
            foreach ($grouplist as $key => $value) {
                $arr=[];
                $value['rule']=explode(',', $value['rule']);
                foreach ($value['rule'] as $k => $v) {
                    $res=\think\Db::name('nav')->where('`id`="'.$v.'"')->find();
                    $arr[]=$res['name']; 
                }
                $grouplist[$key]['rule']=$arr;
                $grouplist[$key]['rule']=implode(' 、', $grouplist[$key]['rule']);
             }
      $this->assign('grouplist', $grouplist);
      // 渲染模板输出
      return $this->fetch();
    }

4、角色添加:

<div class="row">
	<div class="col-lg-12 col-sm-12 col-xs-12">
	    <div class="widget">
	        <div class="widget-header bordered-bottom bordered-themeprimary">
	            <span class="widget-caption">角色添加</span>
	        </div>
            <div class="widget-body">
                    <form class="form-horizontal form-bordered" role="form" method="post" action="" >
                        <div class="form-group">
                            <label for="inputusername" class="col-sm-1 control-label no-padding-right">角色</label>
                            <div class="col-sm-4">
                                <input type="text" class="form-control"  name="name" placeholder="角色">
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputusername" class="col-sm-1 control-label no-padding-right">描述</label>
                            <div class="col-sm-4">
                               <input type="text" class="form-control"  placeholder="描述"  name="desc" >
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputusername" class="col-sm-1 control-label no-padding-right">拥有权限</label>
                            <div class="col-sm-4">
                                <?php foreach($yjmenu as $yjk=>$yjr){ ?>
                                            <label>
                                                <input name="rule[]" type="checkbox" class="inverted" value="<?php echo $yjr['id'];?>">
                                                <span class="text">&nbsp;<?php echo $yjr['name'];?></span>
                                            </label><br/>
                                            <?php if(!empty($yjr['sub'])){?>
                                            <?php foreach($yjr["sub"] as $subk=>$subr){ ?>
                                            <label>
                                                <input name="rule[]" type="checkbox" class="inverted" value="<?php echo $subr['id'];?>">&nbsp;&nbsp;|-
                                                <span class="text">&nbsp;<?php echo $subr['name'];?></span>
                                            </label><br/>
                                            <?php }?>
                                            <?php }?>
                                        <?php }?>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-sm-offset-1 col-sm-10">
                                <button type="submit" class="btn btn-primary">添加</button>
                            </div>
                        </div>
                    </form>
            </div>
	    </div>
	</div>
</div>

PHP 代码:

    public function groupadd(){
        if(request()->isPost()){
            $data=[
                'id'=>input('id'),
                'name'=>input('name'),
                'desc'=>input('desc'), 
                'rule'=>implode(',',input('rule/a')),
            ];
            // var_dump($data['rule']);exit();
            $validate = \think\Loader::validate('group');
            if($validate->check($data)){

                $res=\think\Db::name('group')->insert($data);
                if($res){
                    return $this->success('添加成功!','grouplist');
                }
                else{
                    return $this->error('添加失败');
                }
            }else{
                return $this->error($validate->getError());
            }
            return;
        }
         return $this->fetch();
    }

遍历公共头部左侧导航:

<ul class="nav sidebar-menu">
    <!--Dashboard-->
    <li>
        <a href="/" target="_blank">
            <i class="menu-icon glyphicon glyphicon-home"></i>
            <span class="menu-text"> 访问首页 </span>
        </a>
    </li>
    <li class="active">
        <a href="{:url('admin/Index/index')}">
            <i class="menu-icon glyphicon glyphicon-tasks"></i>
            <span class="menu-text"> 控制台 </span>
        </a>
    </li>
    <?php foreach($yjmenu as $yjk=>$yjr){ 
            if(in_array($yjr['id'],$limitarr)){
            ?>
    <li {if condition="($controller_name eq $yjr['co'])"}class="active open"{/if}>
        <a href="#" class="menu-dropdown">
            <i class="menu-icon fa fa-desktop"></i>
            <span class="menu-text"> <?php echo $yjr["name"];?> </span>
            <i class="menu-expand"></i>
        </a>
    <?php if(!empty($yjr['sub'])){?>
        <ul class="submenu">
            <?php foreach($yjr["sub"] as $subk=>$subr){
                if(in_array($subr['id'],$limitarr)){
                ?>
            <li {if condition="($controller_name eq $subr['co']) and ($action_name eq $subr['ac'])"}class="active"{/if}{$subr['co']}{$subr['ac']}>
                <a href="<?php echo url($subr["url"]);?>">
                    <span class="menu-text"><?php echo $subr["name"];?></span>
                </a>
            </li>
             <?php } }?>
        </ul>
    <?php } ?>
    </li>
    <?php } }?>
</ul>

PHP代码:见公共控制器 Base.php 文件


三、最后一步:所有控制器都要继承公共控制器。

登录方法:登录成功之后 session 记录用户名,查询数据库,并记录权限值。

    public function index(){
    	if(request()->isPost()){
			// 验证码判断
			$username=input('username');
    		        $password=input('password');
			$map['username'] = $username;
			$map['stop'] = 1;
			$user=\think\Db::name('admin')->where($map)->find();
			if($user==''){
				return $this->error('账号不存在!');
			}else{
				\think\Session::set('id',$user['id']);
				\think\Session::set('group_id',$user['group_id']);
				\think\Session::set('img',$user['img']);
				// 权限记录
				$groupdata=\think\Db::name('group')->where('id','=',session('group_id'))->find();
				// halt($groupdata);
				\think\Session::set('adminrule',$groupdata['rule']);
				// 登录记录
				$data=[
		            'login_name'=>session('username'),
		            'group_id'=>session('group_id'),
	            ];
				return $this->success('登录成功,正在跳转!','admin/Index/index');
			}
		}
      return $this->fetch();
    }

创建公共控制器Base.php

<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
class Base extends Controller
{
    public function _initialize(){
           if(!session('id')){
                $this->error('请先登录系统',url('admin/Login/index'));
           }else{
            $request=Request::instance();
            $cn=$request->controller();
            $an=$request->action();
            $this->assign('action_name',$an);
            $this->assign('controller_name',$cn);
            $limitarr=session('adminrule');
           // halt(session('adminrule'));
           $nav= \think\Db::name('nav')->where('`id` in ('.Session('adminrule').')')->select();
           // $corule=M("nav")->where('`nav_id` in ('.$_SESSION['adminCount']['rule'].')')->select();
           // halt($nav);
           $arrrule=array();
            foreach ($nav as $k => $v) {
              $arrrule[]=$v["co"];
            }
            // halt($arrrule);
            if(in_array($cn,$arrrule)){
        }else{
           if($cn=="Index"){
           }else{
            return $this->error('你没有权限!!',url('admin/Index/index'));
           }
        }
           }
           $this->nav();
           $this->item();
    }
    public function nav(){
    	$yjmenu= \think\Db::name('nav')->where('pid=0 AND type=1')->order('sort asc')->select();
	    foreach ($yjmenu as $mk => $mr) {
	       $submenu= \think\Db::name('nav')->where('pid','=',$mr['id'])->select();
	       if($submenu){
	           $yjmenu[$mk]['sub']=$submenu;
	       }
	    }

    // $limitarr=session('adminrule');

	    $limitarr=explode(",", session('adminrule'));
	    $this->assign('yjmenu', $yjmenu);
	    $this->assign('submenu', $yjmenu);
	    $this->assign('limitarr', $limitarr);
	    $request=Request::instance();
	    $cn=$request->controller();
	    $an=$request->action();
	    $this->assign('action_name',$an);
	    $this->assign('controller_name',$cn);
	}



  • 暂无任何回答