ThinkPHP学习札记(十九)权限管理的实现方式RBAC
ThinkPHP学习笔记(十九)权限管理的实现方式RBAC
Action的方法
<?php /** * 基于权限的角色访问控制 * Full扩展保重的RBAC.class.php * * 安全拦截器 * * 认证管理器(识别不同身份) * * 决策访问管理器(即时模式:立即生效;登录模式:下次登录时生效) * * 运行身份管理(单身份、多身份管理B/S) * * * 需要当前类和Public和Common类 * PublicAction:做用户登录和退出 * CommonAction:初始化接口,需要在这个里面写上一个初始化接口来实现对权限的认证和修改,每个方法都会经过他’ * 如果不需要验证的模块,则不需要继承CommonAction * 1.去RBAC.class.php中拷贝需要创建的数据库表 * 需要修改access表,加入`pid` int(11) NOT NULL,这个字段 CREATE TABLE IF NOT EXISTS `think_access` ( `role_id` smallint(6) unsigned NOT NULL, `node_id` smallint(6) unsigned NOT NULL, `level` tinyint(1) NOT NULL, `module` varchar(50) DEFAULT NULL, `pid` int(11) NOT NULL, KEY `groupId` (`role_id`), KEY `nodeId` (`node_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `think_node` ( `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `title` varchar(50) DEFAULT NULL, `status` tinyint(1) DEFAULT '0', `remark` varchar(255) DEFAULT NULL, `sort` smallint(6) unsigned DEFAULT NULL, `pid` smallint(6) unsigned NOT NULL, `level` tinyint(1) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `level` (`level`), KEY `pid` (`pid`), KEY `status` (`status`), KEY `name` (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `think_role` ( `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `pid` smallint(6) DEFAULT NULL, `status` tinyint(1) unsigned DEFAULT NULL, `remark` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `pid` (`pid`), KEY `status` (`status`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; CREATE TABLE IF NOT EXISTS `think_role_user` ( `role_id` mediumint(9) unsigned DEFAULT NULL, `user_id` char(32) DEFAULT NULL, KEY `group_id` (`role_id`), KEY `user_id` (`user_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; * * 2.创建用户表的必须字段:id、username、password * 五张表的对应关系: * 节点表:think_node * 权限表: think_access( * 项目模块和方法之间的关系; * 用户访问项目(level为1)、模块(level为2)、方法(level为3)直接的关系用节点来表示) * 权限组:think_role * 用户表:tb_user * 用户和组的对应关系:think_role_user * access控制组与模块方法的关系 * 3.修改配置文件 * 4.修改CommonAction * 5.当前方法需要继承CommonAction */ class RbacAction extends CommonAction{ public function index(){ } public function add(){ } public function update(){ } public function delete(){ } } ?>
下面上一下五张表的数据
tb_user:用户表
Role权限组表
role_user:权限组与用户的对应关系表
node表:表示当前项目中url分类,精确到每个方法的控制
access表:表示不同用户组对应的可以访问的不同url分类
config中需要设置的参数:
//设置rbac的参数 'USER_AUTH_ON'=>true, 'USER_AUTH_TYPE' =>1, // 默认认证类型 1 登录认证 2 即使认证 'USER_AUTH_KEY' =>'authId', // 用户认证SESSION标记 'ADMIN_AUTH_KEY' =>'administrator',//管理员标识 'USER_AUTH_MODEL' =>'User', // 默认验证数据表模型 'AUTH_PWD_ENCODER' =>'md5', // 用户认证密码加密方式 'USER_AUTH_GATEWAY' =>'/Public/login', // 默认认证网关 'NOT_AUTH_MODULE' =>'Public', // 默认无需认证模块 'REQUIRE_AUTH_MODULE'=>'', // 默认需要认证模块 'NOT_AUTH_ACTION' =>'', // 默认无需认证操作 'REQUIRE_AUTH_ACTION'=>'', // 默认需要认证操作 'GUEST_AUTH_ON' => false, // 是否开启游客授权访问 'GUEST_AUTH_ID' => 0, // 游客的用户ID(可以在数据库组中设置一个id为0的游客组) 'SHOW_RUN_TIME'=>true, // 运行时间显示 'SHOW_ADV_TIME'=>true, // 显示详细的运行时间 'SHOW_DB_TIMES'=>true, // 显示数据库查询和写入次数 'SHOW_CACHE_TIMES'=>true, // 显示缓存操作次数 'SHOW_USE_MEM'=>true, // 显示内存开销 'DB_LIKE_FIELDS'=>'title|remark', 'RBAC_ROLE_TABLE'=>'think_role', 'RBAC_USER_TABLE' => 'think_role_user', 'RBAC_ACCESS_TABLE' => 'think_access', 'RBAC_NODE_TABLE' => 'think_node',
PublicAction中需要设置的公共访问方法;(命名基于配置中的NOT_AUTH_MODULE的配置)
<?php /** * 基于权限的角色访问控制 * Full扩展保重的RBAC.class.php * 主要用于登录和退出 * */ class PublicAction extends Action{ public function index(){ $this->login(); } public function login(){ $this->display(); } //可以去例子中复制 public function checkLogin(){ if(empty($_POST['username'])) { $this->error('帐号错误!'); }elseif (empty($_POST['password'])){ $this->error('密码必须!'); // }elseif (empty($_POST['verify'])){ // $this->error('验证码必须!'); } //生成认证条件 $map = array(); // 支持使用绑定帐号登录 $map['username'] = $_POST['username']; // $map["status"] = array('gt',0); // if($_SESSION['verify'] != md5($_POST['verify'])) { // $this->error('验证码错误!'); // } import ( 'ORG.Util.RBAC' ); $authInfo = RBAC::authenticate($map); //使用用户名、密码和状态的方式进行认证 if(false === $authInfo) { $this->error('帐号不存在或已禁用!'); }else { if($authInfo['password'] != md5($_POST['password'])) { $this->error('密码错误!'); } $_SESSION[C('USER_AUTH_KEY')] = $authInfo['id']; // $_SESSION['email'] = $authInfo['email']; // $_SESSION['loginUserName'] = $authInfo['nickname']; // $_SESSION['lastLoginTime'] = $authInfo['last_login_time']; // $_SESSION['login_count'] = $authInfo['login_count']; if($authInfo['username']=='admin') { $_SESSION['administrator'] = true; } //保存登录信息 // $User = M('User'); // $ip = get_client_ip(); // $time = time(); // $data = array(); // $data['id'] = $authInfo['id']; // $data['last_login_time'] = $time; // $data['login_count'] = array('exp','login_count+1'); // $data['last_login_ip'] = $ip; // $User->save($data); // 缓存访问权限 RBAC::saveAccessList(); $this->success('登录成功!'); } } //可以去例子中复制 public function loginout(){ if(isset($_SESSION[C('USER_AUTH_KEY')])) { unset($_SESSION[C('USER_AUTH_KEY')]); unset($_SESSION); session_destroy(); $this->assign("jumpUrl",__URL__.'/login/'); $this->success('登出成功!'); }else { $this->error('已经登出!'); } } } ?>
CommonAction中设置所有url的过滤方法
<?php /** * ThinkPHP中的 * 让其他的Action继承当前的CommonAction就可以了 */ class CommonAction extends Action{ //去文档的模型扩展看(_initialize方法可以去例子中查找) function _initialize() { // 用户权限检查 if (C ( 'USER_AUTH_ON' ) && !in_array(MODULE_NAME,explode(',',C('NOT_AUTH_MODULE')))) { import ( 'ORG.Util.RBAC' ); if (! RBAC::AccessDecision ()) { //检查认证识别号 if (! $_SESSION [C ( 'USER_AUTH_KEY' )]) { //跳转到认证网关 redirect ( PHP_FILE . C ( 'USER_AUTH_GATEWAY' ) ); } // 没有权限 抛出错误 if (C ( 'RBAC_ERROR_PAGE' )) { // 定义权限错误页面 redirect ( C ( 'RBAC_ERROR_PAGE' ) ); } else { if (C ( 'GUEST_AUTH_ON' )) { $this->assign ( 'jumpUrl', PHP_FILE . C ( 'USER_AUTH_GATEWAY' ) ); } // 提示错误信息 $this->error ( L ( '_VALID_ACCESS_' ) ); } } } } public function verify(){ //导入验证码类 //方式一: import('ORG.Util.Image'); //方式二:@代表当前项目的lib文件夹(需要自己复制或者自己写一个新的类) // import('@.ORG.Image') // Image::buildImageVerify(); //扩展修改 /** * @param string $length 位数 * @param string $mode 类型(0字母,1数字,2大写字母,3小写字母,4中文,5混合) * @param string $type 图像格式 * @param string $width 宽度 * @param string $height 高度 * buildImageVerify($length=4,$mode=1,$type='png',$width=48,$height=22,$verifyName='verify') */ Image::buildImageVerify(5,5,'png',80,22); //中文验证码(2.0会有一个问题:msubstr有错误) //1.修改function::msubstr //2.加入字体ttf需要放入image同级目录之下 //扩展可以去类文件中查看 // Image::GBVerify(); } } ?>
Public文件夹下的login。html
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title>

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

많은 사용자들이 스마트 시계를 선택할 때 Huawei 브랜드를 선택하게 됩니다. 그 중 Huawei GT3pro와 GT4가 가장 인기 있는 선택입니다. 두 제품의 차이점을 궁금해하는 사용자가 많습니다. Huawei GT3pro와 GT4의 차이점은 무엇입니까? 1. 외관 GT4: 46mm와 41mm, 재질은 유리 거울 + 스테인레스 스틸 본체 + 고해상도 섬유 후면 쉘입니다. GT3pro: 46.6mm 및 42.9mm, 재질은 사파이어 유리 + 티타늄 본체/세라믹 본체 + 세라믹 백 쉘입니다. 2. 건강한 GT4: 최신 Huawei Truseen5.5+ 알고리즘을 사용하면 결과가 더 정확해집니다. GT3pro: ECG 심전도, 혈관 및 안전성 추가

Windows 11에서 캡처 도구가 작동하지 않는 이유 문제의 근본 원인을 이해하면 올바른 솔루션을 찾는 데 도움이 될 수 있습니다. 캡처 도구가 제대로 작동하지 않는 주요 이유는 다음과 같습니다. 초점 도우미가 켜져 있습니다. 이렇게 하면 캡처 도구가 열리지 않습니다. 손상된 응용 프로그램: 캡처 도구가 실행 시 충돌하는 경우 응용 프로그램이 손상되었을 수 있습니다. 오래된 그래픽 드라이버: 호환되지 않는 드라이버가 캡처 도구를 방해할 수 있습니다. 다른 응용 프로그램의 간섭: 실행 중인 다른 응용 프로그램이 캡처 도구와 충돌할 수 있습니다. 인증서가 만료되었습니다. 업그레이드 프로세스 중 오류로 인해 이 문제가 발생할 수 있습니다. 이 문제는 대부분의 사용자에게 적합하며 특별한 기술 지식이 필요하지 않습니다. 1. Windows 및 Microsoft Store 앱 업데이트

JavaScript에서 undefound와 null은 모두 "아무것도 없음"이라는 개념을 나타냅니다. 1. undefine은 초기화되지 않은 변수 또는 존재하지 않는 속성을 나타냅니다. 변수가 선언되었지만 값이 할당되지 않은 경우 변수의 값은 undefine입니다. 개체에 존재하지 않는 속성에 액세스하는 경우 반환된 값도 정의되지 않습니다. 2. null은 빈 개체 참조를 나타내는 경우가 있으며, 개체 참조가 차지하는 메모리를 해제하기 위해 null로 설정할 수 있습니다.

C 언어에서 null과 NULL의 차이점은 다음과 같습니다. null은 C 언어의 매크로 정의로, 일반적으로 포인터 변수를 초기화하거나 조건문에서 포인터가 null인지 확인하는 데 사용할 수 있는 null 포인터를 나타내는 데 사용됩니다. NULL은 C 언어의 매크로 정의입니다. 일반적으로 널 포인터, 널 포인터 배열 또는 널 구조 포인터를 나타내는 데 사용되는 널 값을 나타내는 데 사용되는 미리 정의된 상수입니다.

현대 소프트웨어 개발에서 신원 인증은 매우 중요한 보안 수단입니다. Auth0은 개발자가 다양한 신원 인증 방법(OAuth2, OpenIDConnect 등)을 신속하게 구현하고 안전하고 신뢰할 수 있는 인증 서비스를 제공하는 데 도움을 주는 회사입니다. 이 기사에서는 JavaAPI 개발에서 인증을 위해 Auth0을 사용하는 방법을 소개합니다. 1단계: Auth0 계정을 만들고 애플리케이션을 등록해야 합니다.

null과 정의되지 않음의 차이점은 다음과 같습니다. 1. 의미론적 의미, 3. 다른 값과의 비교, 5. 함수 매개변수와의 관계, 7. 성능 고려 사항, . JSON 직렬화의 성능 9. 유형과의 관계. 자세한 소개: 1. 의미론적 의미인 null은 일반적으로 이 변수에 유효한 개체 값이 없음을 의미하는 반면, 정의되지 않음은 일반적으로 변수에 값이 할당되지 않았거나 개체에 이 속성이 없음을 의미합니다. , 등.

Null과 정의되지 않음은 모두 값이 부족하거나 정의되지 않은 상태를 나타냅니다. 사용 시나리오에 따라 Null 또는 정의되지 않음을 사용하도록 선택하는 몇 가지 기본 원칙이 있습니다. 1. 변수가 비어 있거나 유효하지 않음을 명확하게 표시해야 하는 경우 null을 사용할 수 있습니다. 2. 변수가 선언되었지만 아직 값이 할당되지 않은 경우 기본적으로 정의되지 않은 상태로 설정됩니다. 3. 변수가 비어 있는지 또는 정의되지 않았는지 확인해야 하는 경우 완전 항등 연산자 "=를 사용합니다. ==" 변수가 null인지 정의되지 않았는지 확인합니다. .

사용법: 1. 참조 유형 변수를 null로 초기화합니다. 이는 변수가 현재 어떤 객체도 가리키지 않음을 나타냅니다. 2. 참조 유형 변수를 null로 설정하면 변수가 참조하는 객체의 메모리 공간을 해제할 수 있습니다. 3. 참조가 비어 있는지 확인하려면 null을 사용하세요. 참조가 null인지 판단하면 NullPointerException이 발생하는 것을 방지할 수 있습니다. 4. 참조가 비어 있는지 판단하려면 null을 사용하세요.
