Browse Source

新增基类token方法
优化后台表单提交安全验证

Karson 6 years ago
parent
commit
d4900be78f

+ 48 - 72
application/admin/controller/auth/Admin.php

@@ -36,24 +36,18 @@ class Admin extends Backend
 
         Tree::instance()->init($groupList);
         $groupdata = [];
-        if ($this->auth->isSuperAdmin())
-        {
+        if ($this->auth->isSuperAdmin()) {
             $result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
-            foreach ($result as $k => $v)
-            {
+            foreach ($result as $k => $v) {
                 $groupdata[$v['id']] = $v['name'];
             }
-        }
-        else
-        {
+        } else {
             $result = [];
             $groups = $this->auth->getGroups();
-            foreach ($groups as $m => $n)
-            {
+            foreach ($groups as $m => $n) {
                 $childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
                 $temp = [];
-                foreach ($childlist as $k => $v)
-                {
+                foreach ($childlist as $k => $v) {
                     $temp[$v['id']] = $v['name'];
                 }
                 $result[__($n['name'])] = $temp;
@@ -70,47 +64,43 @@ class Admin extends Backend
      */
     public function index()
     {
-        if ($this->request->isAjax())
-        {
+        if ($this->request->isAjax()) {
             //如果发送的来源是Selectpage,则转发到Selectpage
-            if ($this->request->request('keyField'))
-            {
+            if ($this->request->request('keyField')) {
                 return $this->selectpage();
             }
             $childrenGroupIds = $this->childrenGroupIds;
             $groupName = AuthGroup::where('id', 'in', $childrenGroupIds)
-                    ->column('id,name');
+                ->column('id,name');
             $authGroupList = AuthGroupAccess::where('group_id', 'in', $childrenGroupIds)
-                    ->field('uid,group_id')
-                    ->select();
+                ->field('uid,group_id')
+                ->select();
 
             $adminGroupName = [];
-            foreach ($authGroupList as $k => $v)
-            {
-                if (isset($groupName[$v['group_id']]))
+            foreach ($authGroupList as $k => $v) {
+                if (isset($groupName[$v['group_id']])) {
                     $adminGroupName[$v['uid']][$v['group_id']] = $groupName[$v['group_id']];
+                }
             }
             $groups = $this->auth->getGroups();
-            foreach ($groups as $m => $n)
-            {
+            foreach ($groups as $m => $n) {
                 $adminGroupName[$this->auth->id][$n['id']] = $n['name'];
             }
             list($where, $sort, $order, $offset, $limit) = $this->buildparams();
             $total = $this->model
-                    ->where($where)
-                    ->where('id', 'in', $this->childrenAdminIds)
-                    ->order($sort, $order)
-                    ->count();
+                ->where($where)
+                ->where('id', 'in', $this->childrenAdminIds)
+                ->order($sort, $order)
+                ->count();
 
             $list = $this->model
-                    ->where($where)
-                    ->where('id', 'in', $this->childrenAdminIds)
-                    ->field(['password', 'salt', 'token'], true)
-                    ->order($sort, $order)
-                    ->limit($offset, $limit)
-                    ->select();
-            foreach ($list as $k => &$v)
-            {
+                ->where($where)
+                ->where('id', 'in', $this->childrenAdminIds)
+                ->field(['password', 'salt', 'token'], true)
+                ->order($sort, $order)
+                ->limit($offset, $limit)
+                ->select();
+            foreach ($list as $k => &$v) {
                 $groups = isset($adminGroupName[$v['id']]) ? $adminGroupName[$v['id']] : [];
                 $v['groups'] = implode(',', array_keys($groups));
                 $v['groups_text'] = implode(',', array_values($groups));
@@ -128,17 +118,15 @@ class Admin extends Backend
      */
     public function add()
     {
-        if ($this->request->isPost())
-        {
+        if ($this->request->isPost()) {
+            $this->token();
             $params = $this->request->post("row/a");
-            if ($params)
-            {
+            if ($params) {
                 $params['salt'] = Random::alnum();
                 $params['password'] = md5(md5($params['password']) . $params['salt']);
                 $params['avatar'] = '/assets/img/avatar.png'; //设置新管理员默认头像。
                 $result = $this->model->validate('Admin.add')->save($params);
-                if ($result === false)
-                {
+                if ($result === false) {
                     $this->error($this->model->getError());
                 }
                 $group = $this->request->post("group/a");
@@ -146,8 +134,7 @@ class Admin extends Backend
                 //过滤不允许的组别,避免越权
                 $group = array_intersect($this->childrenGroupIds, $group);
                 $dataset = [];
-                foreach ($group as $value)
-                {
+                foreach ($group as $value) {
                     $dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
                 }
                 model('AuthGroupAccess')->saveAll($dataset);
@@ -161,23 +148,20 @@ class Admin extends Backend
     /**
      * 编辑
      */
-    public function edit($ids = NULL)
+    public function edit($ids = null)
     {
         $row = $this->model->get(['id' => $ids]);
-        if (!$row)
+        if (!$row) {
             $this->error(__('No Results were found'));
-        if ($this->request->isPost())
-        {
+        }
+        if ($this->request->isPost()) {
+            $this->token();
             $params = $this->request->post("row/a");
-            if ($params)
-            {
-                if ($params['password'])
-                {
+            if ($params) {
+                if ($params['password']) {
                     $params['salt'] = Random::alnum();
                     $params['password'] = md5(md5($params['password']) . $params['salt']);
-                }
-                else
-                {
+                } else {
                     unset($params['password'], $params['salt']);
                 }
                 //这里需要针对username和email做唯一验证
@@ -187,8 +171,7 @@ class Admin extends Backend
                     'email'    => 'require|email|unique:admin,email,' . $row->id
                 ]);
                 $result = $row->validate('Admin.edit')->save($params);
-                if ($result === false)
-                {
+                if ($result === false) {
                     $this->error($row->getError());
                 }
 
@@ -201,8 +184,7 @@ class Admin extends Backend
                 $group = array_intersect($this->childrenGroupIds, $group);
 
                 $dataset = [];
-                foreach ($group as $value)
-                {
+                foreach ($group as $value) {
                     $dataset[] = ['uid' => $row->id, 'group_id' => $value];
                 }
                 model('AuthGroupAccess')->saveAll($dataset);
@@ -212,8 +194,7 @@ class Admin extends Backend
         }
         $grouplist = $this->auth->getGroups($row['id']);
         $groupids = [];
-        foreach ($grouplist as $k => $v)
-        {
+        foreach ($grouplist as $k => $v) {
             $groupids[] = $v['id'];
         }
         $this->view->assign("row", $row);
@@ -226,23 +207,19 @@ class Admin extends Backend
      */
     public function del($ids = "")
     {
-        if ($ids)
-        {
+        if ($ids) {
             // 避免越权删除管理员
             $childrenGroupIds = $this->childrenGroupIds;
-            $adminList = $this->model->where('id', 'in', $ids)->where('id', 'in', function($query) use($childrenGroupIds) {
-                        $query->name('auth_group_access')->where('group_id', 'in', $childrenGroupIds)->field('uid');
-                    })->select();
-            if ($adminList)
-            {
+            $adminList = $this->model->where('id', 'in', $ids)->where('id', 'in', function ($query) use ($childrenGroupIds) {
+                $query->name('auth_group_access')->where('group_id', 'in', $childrenGroupIds)->field('uid');
+            })->select();
+            if ($adminList) {
                 $deleteIds = [];
-                foreach ($adminList as $k => $v)
-                {
+                foreach ($adminList as $k => $v) {
                     $deleteIds[] = $v->id;
                 }
                 $deleteIds = array_diff($deleteIds, [$this->auth->id]);
-                if ($deleteIds)
-                {
+                if ($deleteIds) {
                     $this->model->destroy($deleteIds);
                     model('AuthGroupAccess')->where('uid', 'in', $deleteIds)->delete();
                     $this->success();
@@ -271,5 +248,4 @@ class Admin extends Backend
         $this->dataLimitField = 'id';
         return parent::selectpage();
     }
-
 }

+ 2 - 0
application/admin/controller/auth/Group.php

@@ -89,6 +89,7 @@ class Group extends Backend
     public function add()
     {
         if ($this->request->isPost()) {
+            $this->token();
             $params = $this->request->post("row/a", [], 'strip_tags');
             $params['rules'] = explode(',', $params['rules']);
             if (!in_array($params['pid'], $this->childrenGroupIds)) {
@@ -127,6 +128,7 @@ class Group extends Backend
             $this->error(__('No Results were found'));
         }
         if ($this->request->isPost()) {
+            $this->token();
             $params = $this->request->post("row/a", [], 'strip_tags');
             // 父节点不能是它自身的子节点
             if (!in_array($params['pid'], $this->childrenGroupIds)) {

+ 2 - 0
application/admin/controller/auth/Rule.php

@@ -69,6 +69,7 @@ class Rule extends Backend
     public function add()
     {
         if ($this->request->isPost()) {
+            $this->token();
             $params = $this->request->post("row/a", [], 'strip_tags');
             if ($params) {
                 if (!$params['ismenu'] && !$params['pid']) {
@@ -96,6 +97,7 @@ class Rule extends Backend
             $this->error(__('No Results were found'));
         }
         if ($this->request->isPost()) {
+            $this->token();
             $params = $this->request->post("row/a", [], 'strip_tags');
             if ($params) {
                 if (!$params['ismenu'] && !$params['pid']) {

+ 2 - 0
application/admin/controller/general/Config.php

@@ -72,6 +72,7 @@ class Config extends Backend
     public function add()
     {
         if ($this->request->isPost()) {
+            $this->token();
             $params = $this->request->post("row/a");
             if ($params) {
                 foreach ($params as $k => &$v) {
@@ -110,6 +111,7 @@ class Config extends Backend
     public function edit($ids = null)
     {
         if ($this->request->isPost()) {
+            $this->token();
             $row = $this->request->post("row/a");
             if ($row) {
                 $configList = [];

+ 1 - 0
application/admin/controller/general/Profile.php

@@ -52,6 +52,7 @@ class Profile extends Backend
     public function update()
     {
         if ($this->request->isPost()) {
+            $this->token();
             $params = $this->request->post("row/a");
             $params = array_filter(array_intersect_key(
                 $params,

+ 1 - 0
application/admin/lang/zh-cn.php

@@ -137,6 +137,7 @@ return [
     'Are you sure you want to delete this item?'            => '确定删除此项?',
     'Are you sure you want to delete or turncate?'          => '确定删除或清空?',
     'Are you sure you want to truncate?'                    => '确定清空?',
+    'Token verification error'                              => 'Token验证错误!',
     'You have no permission'                                => '你没有权限访问',
     'Please enter your username'                            => '请输入你的用户名',
     'Please enter your password'                            => '请输入你的密码',

+ 1 - 0
application/admin/view/auth/admin/add.html

@@ -1,4 +1,5 @@
 <form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
+    {:token()}
     <div class="form-group">
         <label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
         <div class="col-xs-12 col-sm-8">

+ 1 - 0
application/admin/view/auth/admin/edit.html

@@ -1,4 +1,5 @@
 <form id="edit-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
+    {:token()}
     <div class="form-group">
         <label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
         <div class="col-xs-12 col-sm-8">

+ 1 - 0
application/admin/view/auth/group/add.html

@@ -1,4 +1,5 @@
 <form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
+    {:token()}
     <input type="hidden" name="row[rules]" value="" />
     <div class="form-group">
         <label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>

+ 1 - 0
application/admin/view/auth/group/edit.html

@@ -1,4 +1,5 @@
 <form id="edit-form" class="form-horizontal form-ajax" role="form" method="POST" action="">
+    {:token()}
     <input type="hidden" name="row[rules]" value="" />
     <div class="form-group">
         <label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>

+ 1 - 0
application/admin/view/auth/rule/add.html

@@ -1,4 +1,5 @@
 <form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST" action="">
+    {:token()}
     <div class="form-group">
         <label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
         <div class="col-xs-12 col-sm-8">

+ 1 - 0
application/admin/view/auth/rule/edit.html

@@ -1,4 +1,5 @@
 <form id="edit-form" class="form-horizontal form-ajax" role="form" method="POST" action="">
+    {:token()}
     <div class="form-group">
         <label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
         <div class="col-xs-12 col-sm-8">

+ 1 - 0
application/admin/view/general/config/index.html

@@ -34,6 +34,7 @@
             <div class="tab-pane fade {$vo.active ? 'active in' : ''}" id="{$vo.name}">
                 <div class="widget-body no-padding">
                     <form id="{$vo.name}-form" class="edit-form form-horizontal" role="form" data-toggle="validator" method="POST" action="{:url('general.config/edit')}">
+                        {:token()}
                         <table class="table table-striped">
                             <thead>
                                 <tr>

+ 1 - 0
application/admin/view/general/profile/index.html

@@ -46,6 +46,7 @@
             <div class="panel-body">
 
                 <form id="update-form" role="form" data-toggle="validator" method="POST" action="{:url('general.profile/update')}">
+                    {:token()}
                     <input type="hidden" id="c-avatar" name="row[avatar]" value="{$admin.avatar|htmlentities}"/>
                     <div class="box-body box-profile">
 

+ 17 - 0
application/common/controller/Backend.php

@@ -10,6 +10,7 @@ use think\Lang;
 use think\Loader;
 use think\Session;
 use fast\Tree;
+use think\Validate;
 
 /**
  * 后台控制器基类
@@ -505,4 +506,20 @@ class Backend extends Controller
         //这里一定要返回有list这个字段,total是可选的,如果total<=list的数量,则会隐藏分页按钮
         return json(['list' => $list, 'total' => $total]);
     }
+
+    /**
+     * 刷新Token
+     */
+    protected function token()
+    {
+        $token = $this->request->post('__token__');
+
+        //验证Token
+        if (!Validate::is($token, "token", ['__token__' => $token])) {
+            $this->error(__('Token verification error'), '', ['__token__' => $this->request->token()]);
+        }
+
+        //刷新Token
+        $this->request->token();
+    }
 }

+ 17 - 0
application/common/controller/Frontend.php

@@ -8,6 +8,7 @@ use think\Controller;
 use think\Hook;
 use think\Lang;
 use think\Loader;
+use think\Validate;
 
 /**
  * 前台控制器基类
@@ -134,4 +135,20 @@ class Frontend extends Controller
     {
         $this->view->config = array_merge($this->view->config ? $this->view->config : [], is_array($name) ? $name : [$name => $value]);
     }
+
+    /**
+     * 刷新Token
+     */
+    protected function token()
+    {
+        $token = $this->request->post('__token__');
+
+        //验证Token
+        if (!Validate::is($token, "token", ['__token__' => $token])) {
+            $this->error(__('Token verification error'), '', ['__token__' => $this->request->token()]);
+        }
+
+        //刷新Token
+        $this->request->token();
+    }
 }

+ 1 - 0
application/index/lang/zh-cn.php

@@ -119,6 +119,7 @@ return [
     'Invalid parameters'                                     => '未知参数',
     'No results were found'                                  => '记录未找到',
     'Parameter %s can not be empty'                          => '参数%s不能为空',
+    'Token verification error'                               => 'Token验证错误!',
     'You have no permission'                                 => '你没有权限访问',
     'An unexpected error occurred'                           => '发生了一个意外错误,程序猿正在紧急处理中',
     'This page will be re-directed in %s seconds'            => '页面将在 %s 秒后自动跳转',