ホームページ バックエンド開発 PHPチュートリアル ThinkPHP学習メモ(19) 権限管理RBACの実装方法

ThinkPHP学習メモ(19) 権限管理RBACの実装方法

Jun 13, 2016 pm 12:54 PM
auth gt null quot user

ThinkPHP学習記(19) 権限管理RBACの実装方法


アクションメソッド

<?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(){
    }
}
?>
ログイン後にコピー

以下は 5 つのテーブルのデータです

tb_user: ユーザーテーブル

ロール権限グループテーブル

role_user: 権限グループとユーザーの対応表

ノード テーブル: 現在のプロジェクトの URL 分類を表し、各メソッドの制御に正確に対応します

アクセス テーブル: さまざまなユーザー グループがアクセスできるさまざまな URL カテゴリを示します

構成で設定する必要があるパラメータ:

//设置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();
	}
}
?>
ログイン後にコピー

パブリックフォルダーの下にログインします。 html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="__URL__/checklogin" method="post">
	用户名:<input type="text" name="username"><br/>
	密码:<input type="text" name="password"><br/>
	<input type="submit" value="登录"><br/>
</form>
</body>
</html>
ログイン後にコピー


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Huawei GT3 ProとGT4の違いは何ですか? Huawei GT3 ProとGT4の違いは何ですか? Dec 29, 2023 pm 02:27 PM

多くのユーザーはスマートウォッチを選ぶときにファーウェイブランドを選択しますが、その中でもファーウェイ GT3pro と GT4 は非常に人気のある選択肢であり、多くのユーザーはファーウェイ GT3pro と GT4 の違いに興味を持っています。 Huawei GT3pro と GT4 の違いは何ですか? 1. 外観 GT4: 46mm と 41mm、材質はガラスミラー + ステンレススチールボディ + 高解像度ファイバーバックシェルです。 GT3pro: 46.6mm および 42.9mm、材質はサファイアガラス + チタンボディ/セラミックボディ + セラミックバックシェルです。 2. 健全な GT4: 最新の Huawei Truseen5.5+ アルゴリズムを使用すると、結果はより正確になります。 GT3pro: ECG 心電図と血管と安全性を追加

修正: Windows 11 で Snipping ツールが機能しない 修正: Windows 11 で Snipping ツールが機能しない Aug 24, 2023 am 09:48 AM

Windows 11 で Snipping Tool が機能しない理由 問題の根本原因を理解すると、適切な解決策を見つけるのに役立ちます。 Snipping Tool が正しく動作しない主な理由は次のとおりです。 フォーカス アシスタントがオンになっている: これにより、Snipping Tool が開かなくなります。破損したアプリケーション: 起動時にスニッピング ツールがクラッシュする場合は、破損している可能性があります。古いグラフィック ドライバー: 互換性のないドライバーは、スニッピング ツールに干渉する可能性があります。他のアプリケーションからの干渉: 実行中の他のアプリケーションが Snipping Tool と競合する可能性があります。証明書の有効期限が切れています: アップグレード プロセス中のエラーにより、この問題が発生する可能性があります。これらの簡単な解決策は、ほとんどのユーザーに適しており、特別な技術知識は必要ありません。 1. Windows および Microsoft Store アプリを更新する

未定義と null は何を意味しますか? 未定義と null は何を意味しますか? Nov 20, 2023 pm 02:39 PM

JavaScript では、未定義と null はどちらも「何もない」という概念を表します: 1. 未定義は初期化されていない変数または存在しないプロパティを表します。変数が宣言されていても値が割り当てられていない場合、変数の値は未定義です。オブジェクト内に存在しないプロパティにアクセスする場合、戻り値も未定義になります; 2. null は空のオブジェクト参照を表します。場合によっては、オブジェクト参照を null に設定して、オブジェクト参照が占有しているメモリを解放できます。

C言語のnullとNULLの違いは何ですか C言語のnullとNULLの違いは何ですか Sep 22, 2023 am 11:48 AM

null と C 言語の NULL の違いは次のとおりです。 null は C 言語のマクロ定義であり、通常は null ポインタを表すために使用され、ポインタ変数を初期化したり、条件文でポインタが null であるかどうかを判断したりするために使用できます。 NULL は、C 言語のマクロ定義です。 の定義済み定数で、通常は NULL 値を表すために使用され、NULL ポインター、NULL ポインター配列、または NULL 構造体ポインターを表すために使用されます。

Java API開発における認証にAuth0を使用する Java API開発における認証にAuth0を使用する Jun 18, 2023 pm 05:30 PM

最新のソフトウェア開発において、ID 認証は非常に重要なセキュリティ対策です。 Auth0 は ID 認証サービスを提供する会社で、開発者が複数の ID 認証方式 (OAuth2、OpenIDConnect など) を迅速に実装し、安全で信頼性の高い認証サービスを提供できるように支援します。この記事では、JavaAPI開発における認証にAuth0を使用する方法を紹介します。ステップ 1: Auth0 アカウントを作成し、アプリケーションを登録します。

nullと未定義の違いは何ですか nullと未定義の違いは何ですか Nov 08, 2023 pm 04:43 PM

null と未定義の違いは次のとおりです: 1. 意味上の意味; 2. 使用シナリオ; 3. 他の値との比較; 4. グローバル変数との関係; 5. 関数パラメーターとの関係; 6. Nullability チェック; 7. パフォーマンスに関する考慮事項; 8 . JSON シリアル化のパフォーマンス; 9. 型との関係。詳細な紹介: 1. セマンティックな意味。null は通常、この変数が有効なオブジェクト値を持たないことがわかっていることを意味し、未定義は通常、変数に値が割り当てられていない、またはオブジェクトにこの属性がないことを意味します。 2. 使用シナリオ、など。

null と unknown を使用する場合 null と unknown を使用する場合 Nov 13, 2023 pm 02:11 PM

null と unknown はどちらも、値が欠落しているか、未定義の状態であることを示します。使用シナリオに応じて、null または unknown の使用を選択するための指針がいくつかあります。1. 変数が空または無効であることを明確に示す必要がある場合、 null を使用できます; 2. 変数が宣言されていても値が割り当てられていない場合、デフォルトで未定義に設定されます; 3. 変数が空か未定義かを確認する必要がある場合は、厳密な等価演算子 "= を使用します。 == 変数が null か未定義かを判断します。

Javaでのnullの用途は何ですか Javaでのnullの用途は何ですか Mar 01, 2024 am 10:10 AM

使用法: 1. 参照型変数を null に初期化し、変数が現在どのオブジェクトも指していないことを示します。 2. 参照型変数を null に設定します。これにより、変数によって参照されるオブジェクトのメモリ領域が解放され、このオブジェクトを回収するガベージコレクタ; 3. 参照が空かどうかを null で判定する 参照が null かどうかを判定することで NullPointerException の発生を回避できる 4. 参照が空かどうかの条件判定に null を使用する

See all articles