123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- <?php
- // +----------------------------------------------------------------------
- // | framework
- // +----------------------------------------------------------------------
- // | 版权所有 2014~2018 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
- // +----------------------------------------------------------------------
- // | 官方网站: http://framework.thinkadmin.top
- // +----------------------------------------------------------------------
- // | 开源协议 ( https://mit-license.org )
- // +----------------------------------------------------------------------
- // | github开源项目:https://github.com/zoujingli/framework
- // +----------------------------------------------------------------------
- namespace app\admin\service;
- use library\tools\Data;
- use library\tools\Node;
- use think\Db;
- /**
- * 权限访问及菜单管理
- * Class AuthService
- * @package app\admin\service
- */
- class AuthService
- {
- /**
- * 权限节点忽略规则
- * @return array
- */
- public static function getIgnore()
- {
- return ['index', 'admin/login', 'admin/index'];
- }
- /**
- * 获取系统代码节点
- * @param array $nodes
- * @return array
- * @throws \ReflectionException
- */
- public static function get($nodes = [])
- {
- list($ignore, $map) = [self::getIgnore(), Node::getClassTreeNode(env('app_path'))];
- $alias = Db::name('SystemNode')->column('node,is_menu,is_auth,is_login,title');
- foreach (Node::getMethodTreeNode(env('app_path')) as $thr => $title) {
- foreach ($ignore as $str) if (stripos($thr, $str) === 0) continue 2;
- $tmp = explode('/', $thr);
- list($one, $two) = ["{$tmp[0]}", "{$tmp[0]}/{$tmp[1]}"];
- $nodes[$one] = array_merge(isset($alias[$one]) ? $alias[$one] : ['node' => $one, 'title' => '', 'is_menu' => 0, 'is_auth' => 0, 'is_login' => 0], ['pnode' => '']);
- $nodes[$two] = array_merge(isset($alias[$two]) ? $alias[$two] : ['node' => $two, 'title' => isset($map[$two]) ? $map[$two] : '', 'is_menu' => 0, 'is_auth' => 0, 'is_login' => 0], ['pnode' => $one]);
- $nodes[$thr] = array_merge(isset($alias[$thr]) ? $alias[$thr] : ['node' => $thr, 'title' => $title, 'is_menu' => 0, 'is_auth' => 0, 'is_login' => 0], ['pnode' => $two]);
- }
- foreach ($nodes as &$node) list($node['is_auth'], $node['is_menu'], $node['is_login']) = [intval($node['is_auth']), intval($node['is_menu']), empty($node['is_auth']) ? intval($node['is_login']) : 1];
- return $nodes;
- }
- /**
- * 检查用户节点权限
- * @param string $node 节点
- * @return boolean
- */
- public static function checkAuthNode($node)
- {
- list($module, $controller, $action) = explode('/', str_replace(['?', '=', '&'], '/', "{$node}///"));
- $current = Node::parseString("{$module}/{$controller}") . strtolower("/{$action}");
- // 后台入口无需要验证权限
- if (stripos($node, 'admin/index') === 0) return true;
- // 超级管理员无需要验证权限
- if (session('user.username') === 'admin') return true;
- // 未配置权限的节点默认放行
- if (!in_array($current, self::getAuthNode())) return true;
- // 用户指定角色授权放行
- return in_array($current, (array)session('user.nodes'));
- }
- /**
- * 获取授权节点
- * @return array
- */
- public static function getAuthNode()
- {
- $nodes = cache('need_access_node');
- if (empty($nodes)) {
- $nodes = Db::name('SystemNode')->where(['is_auth' => '1'])->column('node');
- cache('need_access_node', $nodes);
- }
- return $nodes;
- }
- /**
- * 应用用户权限节点
- * @return boolean
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public static function applyNode()
- {
- cache('need_access_node', null);
- if (($uid = session('user.id'))) session('user', Db::name('SystemUser')->where('id', $uid)->find());
- if (session('user.authorize') && ($ids = explode(',', session('user.authorize')))) {
- $auths = Db::name('SystemAuth')->whereIn('id', $ids)->where('status', '1')->column('id');
- if (empty($auths)) return session('user.nodes', []);
- return session('user.nodes', Db::name('SystemAuthNode')->whereIn('auth', $auths)->column('node'));
- }
- return false;
- }
- /**
- * 判断用户登录状态
- * @return boolean
- */
- public static function isLogin()
- {
- return !!session('user');
- }
- /**
- * 获取授权后的菜单
- * @return array
- * @throws \ReflectionException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public static function getAuthMenu()
- {
- self::applyNode();
- $list = Db::name('SystemMenu')->where('status', '1')->order('sort asc,id asc')->select();
- return self::buildMenuData(Data::arr2tree($list), self::get(), self::isLogin());
- }
- /**
- * 后台主菜单权限过滤
- * @param array $menus 当前菜单列表
- * @param array $nodes 系统权限节点数据
- * @param bool $isLogin 是否已经登录
- * @return array
- */
- private static function buildMenuData($menus, $nodes, $isLogin)
- {
- foreach ($menus as $key => &$menu) {
- if (!empty($menu['sub'])) $menu['sub'] = self::buildMenuData($menu['sub'], $nodes, $isLogin);
- if (!empty($menu['sub'])) $menu['url'] = '#';
- elseif (preg_match('/^https?\:/i', $menu['url'])) continue;
- elseif ($menu['url'] !== '#') {
- $node = join('/', array_slice(explode('/', preg_replace('/[\W]/', '/', $menu['url'])), 0, 3));
- $menu['url'] = url($menu['url']) . (empty($menu['params']) ? '' : "?{$menu['params']}");
- if (isset($nodes[$node]) && $nodes[$node]['is_login'] && empty($isLogin)) unset($menus[$key]);
- elseif (isset($nodes[$node]) && $nodes[$node]['is_auth'] && $isLogin && !self::checkAuthNode($node)) unset($menus[$key]);
- } else unset($menus[$key]);
- }
- return $menus;
- }
- /**
- * 检查密码是否合法
- * @param string $password
- * @return array
- */
- public static function checkPassword($password)
- {
- $password = trim($password);
- if (!strlen($password) >= 6) {
- return ['code' => 0, 'msg' => '密码必须大于6字符!'];
- }
- if (!preg_match("/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,32}$/", $password)) {
- return ['code' => 0, 'msg' => '密码必需包含大小写字母、数字、符号任意两者组合!'];
- }
- return ['code' => 1, 'msg' => '密码复杂度通过验证!'];
- }
- }
|