![Access Control with Bit Masks Access Control with Bit Masks](https://i-blog.csdnimg.cn/blog_migrate/5d30f4c807c955b80c17a58eeabc47d8.png)
![带位掩码的访问控制 Access Control with Bit Masks](https://i-blog.csdnimg.cn/blog_migrate/5d30f4c807c955b80c17a58eeabc47d8.png)
Access Control with Bit Masks Today I want to tell you about the organization of access rights to users (on your site) using bit masks. Perhaps you have already known it, probably not, but anyway I want to give you this information. Why bit masks – easy, because this is and fast and easy way to recognize user’s possibilities. In our system, I have identified six possible actions (it will keep 6 bits, each bit – one of the possible actions). There are next actions: Read, Create, Edit Own, Delete Own, Edit Any and Delete Any (moderator’s / admin’s actions). It can be applied to everything – blogs, news articles, photos and more. Ok, lets start.
使用位掩码的访问控制今天,我想向您介绍使用位掩码对用户(在您的站点上)的访问权限的组织。 也许您已经知道了,也许不是,但是无论如何我想给您这些信息。 为什么要使用位掩码–简单,因为这是识别用户可能性的快速简便的方法。 在我们的系统中,我确定了六个可能的操作(它将保留6位,每个位–一种可能的操作)。 接下来有以下操作:读取,创建,自己编辑,删除自己,编辑任何内容和删除任何内容(主持人/管理员的操作)。 它可以应用于所有内容-博客,新闻文章,照片等。 好的,让我们开始吧。
Here are a little of theory about Bitwise Operators:
以下是有关按位运算符的一些理论知识:
Example | Name | Result |
---|---|---|
$a & $b | And | Bits that are set in both $a and $b are set. |
$a | $b | Or (inclusive or) | Bits that are set in either $a or $b are set. |
$a ^ $b | Xor (exclusive or) | Bits that are set in $a or $b but not both are set. |
~ $a | Not | Bits that are set in $a are not set, and vice versa. |
$a << $b | Shift left | Shift the bits of $a $b steps to the left (each step means “multiply by two”) |
$a >> $b | Shift right | Shift the bits of $a $b steps to the right (each step means “divide by two”) |
例 | 名称 | 结果 |
---|---|---|
$a & $b | 和 | $ a和$ b都设置的位被置位。 |
$a | $b | 或(包含或) | $ a或$ b中设置的位被置位。 |
$a ^ $b | 异或(异或) | $ a或$ b中设置的位,但未同时设置。 |
~ $a | 不 | $ a中设置的位未设置,反之亦然。 |
$a << $b | 左移 | 将$ a $ b步骤的位向左移动(每个步骤表示“乘以2”) |
$a >> $b | 右移 | 向右移动$ a $ b步骤的位(每个步骤表示“除以二”) |
现场演示
打包下载
Now – download the source files and lets start coding !
现在–下载源文件并开始编码!
步骤1. HTML (Step 1. HTML)
Our demo uses 3 html template files:
我们的演示使用3个html模板文件:
main_page.html (main_page.html)
<!DOCTYPE html>
<html lang="en" >
<head>
<title>Access Control with Bit Masks</title>
<link href="css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<header>
<h2>Access Control with Bit Masks</h2>
<a href="https://www.script-tutorials.com/access-control-with-bit-masks/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
</header>
<div class="container">
{form}
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en" >
<head>
<title>Access Control with Bit Masks</title>
<link href="css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<header>
<h2>Access Control with Bit Masks</h2>
<a href="https://www.script-tutorials.com/access-control-with-bit-masks/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
</header>
<div class="container">
{form}
</div>
</body>
</html>
This is very easy layout, isn’t it?. Next one template file:
这是非常简单的布局,不是吗? 下一个模板文件:
login_form.html (login_form.html)
<div class="column">
<h3>Access control demonstration</h3>
<p>You can use next usernames "User", "Writer", "Moderator" and "Admin" and password "password" to login in system. Each of them have own set of possibilities.</p>
</div>
<div class="column">
<form class="login_form" action="index.php" method="post">
<h3>Log In</h3>
<label>Username:</label><input type="text" name="username">
<label>Password:</label><input type="password" name="password">
<input type="submit" name="LogIn" value="Login">
</form>
</div>
<div class="column">
<h3>Access control demonstration</h3>
<p>You can use next usernames "User", "Writer", "Moderator" and "Admin" and password "password" to login in system. Each of them have own set of possibilities.</p>
</div>
<div class="column">
<form class="login_form" action="index.php" method="post">
<h3>Log In</h3>
<label>Username:</label><input type="text" name="username">
<label>Password:</label><input type="password" name="password">
<input type="submit" name="LogIn" value="Login">
</form>
</div>
Another one easy template for login form. Next one template file:
另一个简单的登录表单模板。 下一个模板文件:
logout_form.html (logout_form.html)
<div class="column">
<h3>Hello {name}</h3>
<h3>Your bit mask:</h3>
<div>{bit_mask}</div>
<h3>Your possibilities:</h3>
<div>{possibilities}</div>
</div>
<div class="column">
<a href="index.php?logout">Log Out</a>
</div>
<div class="column">
<h3>Hello {name}</h3>
<h3>Your bit mask:</h3>
<div>{bit_mask}</div>
<h3>Your possibilities:</h3>
<div>{possibilities}</div>
</div>
<div class="column">
<a href="index.php?logout">Log Out</a>
</div>
This is template where we will display our possibilities and link to logout.
这是模板,我们将在其中显示我们的可能性并链接到注销。
步骤2. CSS (Step 2. CSS)
css / main.css (css/main.css)
This file contains several styles of our page layout, no need to publish it today.
该文件包含我们页面布局的几种样式,无需今天发布。
步骤3. PHP (Step 3. PHP)
Now, lets review our main functionality:
现在,让我们回顾一下我们的主要功能:
index.php (index.php)
<?php
// define bit mask for access rights
define('CAN_READ', 1 << 0); // 000001
define('CAN_CREATE', 1 << 1); // 000010
define('CAN_EDIT_OWN', 1 << 2); // 000100
define('CAN_DELETE_OWN', 1 << 3); // 001000
define('CAN_EDIT_ANY', 1 << 4); // 010000
define('CAN_DELETE_ANY', 1 << 5); // 100000
// login system init and generation code
$oSimpleAccessSystem = new SimpleAccessSystem();
$sLoginForm = $oSimpleAccessSystem->getLoginBox();
echo strtr(file_get_contents('main_page.html'), array('{form}' => $sLoginForm));
// class SimpleAccessSystem
class SimpleAccessSystem {
// variables
var $aMembers; // Existed members array
// constructor
function SimpleAccessSystem() {
session_start();
// different sets of permissions
$sUserPerm = CAN_READ;
$sWriterPerm = CAN_READ | CAN_CREATE | CAN_EDIT_OWN | CAN_DELETE_OWN;
$sModeratorPerm = CAN_READ | CAN_EDIT_ANY | CAN_DELETE_ANY;
$sAdminPerm = CAN_READ | CAN_CREATE | CAN_EDIT_OWN | CAN_DELETE_OWN | CAN_EDIT_ANY | CAN_DELETE_ANY;
/* hash = sha1(md5('password') . 'testing'); */
$this->aMembers = array(
'User' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => $sUserPerm),
'Writer' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => $sWriterPerm),
'Moderator' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => $sModeratorPerm),
'Admin' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => $sAdminPerm)
);
}
// get login box function
function getLoginBox() {
if (isset($_GET['logout'])) { // logout processing
if (isset($_SESSION['member_name']) && isset($_SESSION['member_pass']))
$this->performLogout();
}
if ($_POST && $_POST['username'] && $_POST['password']) { // login processing
if ($this->checkLogin($_POST['username'], $_POST['password'], false)) { // successful login
$this->performLogin($_POST['username'], $_POST['password']);
header( "Location:{$_SERVER['REQUEST_URI']}" );
exit;
} else { // wrong login
ob_start(); // get template of Login form
require_once('login_form.html');
$sLoginForm = ob_get_clean();
return $sLoginForm . '<h2>Username or Password is incorrect</h2>';
}
} else { // in case if we already logged (on refresh page):
if (isset($_SESSION['member_name']) && $_SESSION['member_name'] && $_SESSION['member_pass']) {
if ($this->checkLogin($_SESSION['member_name'], $_SESSION['member_pass'])) {
$sRule = $this->aMembers[$_SESSION['member_name']]['rule'];
$sPermissions = '';
$sPermissions .= $this->isCanRead($sRule);
$sPermissions .= $this->isCanCreate($sRule);
$sPermissions .= $this->isCanEdit($sRule);
$sPermissions .= $this->isCanEditAny($sRule);
$sPermissions .= $this->isCanDelete($sRule);
$sPermissions .= $this->isCanDeleteAny($sRule);
ob_start(); // get template of Logout form
require_once('logout_form.html');
$sLogoutForm = ob_get_clean();
$sLogoutForm = str_replace('{name}', $_SESSION['member_name'], $sLogoutForm);
$sLogoutForm = str_replace('{bit_mask}', $sRule, $sLogoutForm);
$sLogoutForm = str_replace('{possibilities}', $sPermissions, $sLogoutForm);
return $sLogoutForm;
}
}
// otherwise - draw login form
ob_start();
require_once('login_form.html');
$sLoginForm = ob_get_clean();
return $sLoginForm;
}
}
// check functions
function isCanRead($sRule) {
return ($sRule & CAN_READ) ? 'You can Read<br />' : '';
}
function isCanCreate($sRule) {
return ($sRule & CAN_CREATE) ? 'You can Create<br />' : '';
}
function isCanEdit($sRule) {
return ($sRule & CAN_EDIT_OWN) ? 'You can Edit<br />' : '';
}
function isCanEditAny($sRule) {
return ($sRule & CAN_EDIT_ANY) ? 'You can Edit anything<br />' : '';
}
function isCanDelete($sRule) {
return ($sRule & CAN_DELETE_OWN) ? 'You can Delete<br />' : '';
}
function isCanDeleteAny($sRule) {
return ($sRule & CAN_DELETE_ANY) ? 'You can Delete anything<br />' : '';
}
// perform login
function performLogin($sName, $sPass) {
$this->performLogout();
$sSalt = $this->aMembers[$sName]['salt'];
$sPass = sha1(md5($sPass) . $sSalt);
$_SESSION['member_name'] = $sName;
$_SESSION['member_pass'] = $sPass;
}
// perform logout
function performLogout() {
unset($_SESSION['member_name']);
unset($_SESSION['member_pass']);
}
// check login
function checkLogin($sName, $sPass, $isHash = true) {
if (isset($this->aMembers[$sName])) {
if (! $isHash) {
$sSalt = $this->aMembers[$sName]['salt'];
$sPass = sha1(md5($sPass) . $sSalt);
}
return ($sPass == $this->aMembers[$sName]['hash']);
}
return false;
}
}
<?php
// define bit mask for access rights
define('CAN_READ', 1 << 0); // 000001
define('CAN_CREATE', 1 << 1); // 000010
define('CAN_EDIT_OWN', 1 << 2); // 000100
define('CAN_DELETE_OWN', 1 << 3); // 001000
define('CAN_EDIT_ANY', 1 << 4); // 010000
define('CAN_DELETE_ANY', 1 << 5); // 100000
// login system init and generation code
$oSimpleAccessSystem = new SimpleAccessSystem();
$sLoginForm = $oSimpleAccessSystem->getLoginBox();
echo strtr(file_get_contents('main_page.html'), array('{form}' => $sLoginForm));
// class SimpleAccessSystem
class SimpleAccessSystem {
// variables
var $aMembers; // Existed members array
// constructor
function SimpleAccessSystem() {
session_start();
// different sets of permissions
$sUserPerm = CAN_READ;
$sWriterPerm = CAN_READ | CAN_CREATE | CAN_EDIT_OWN | CAN_DELETE_OWN;
$sModeratorPerm = CAN_READ | CAN_EDIT_ANY | CAN_DELETE_ANY;
$sAdminPerm = CAN_READ | CAN_CREATE | CAN_EDIT_OWN | CAN_DELETE_OWN | CAN_EDIT_ANY | CAN_DELETE_ANY;
/* hash = sha1(md5('password') . 'testing'); */
$this->aMembers = array(
'User' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => $sUserPerm),
'Writer' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => $sWriterPerm),
'Moderator' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => $sModeratorPerm),
'Admin' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing', 'rule' => $sAdminPerm)
);
}
// get login box function
function getLoginBox() {
if (isset($_GET['logout'])) { // logout processing
if (isset($_SESSION['member_name']) && isset($_SESSION['member_pass']))
$this->performLogout();
}
if ($_POST && $_POST['username'] && $_POST['password']) { // login processing
if ($this->checkLogin($_POST['username'], $_POST['password'], false)) { // successful login
$this->performLogin($_POST['username'], $_POST['password']);
header( "Location:{$_SERVER['REQUEST_URI']}" );
exit;
} else { // wrong login
ob_start(); // get template of Login form
require_once('login_form.html');
$sLoginForm = ob_get_clean();
return $sLoginForm . '<h2>Username or Password is incorrect</h2>';
}
} else { // in case if we already logged (on refresh page):
if (isset($_SESSION['member_name']) && $_SESSION['member_name'] && $_SESSION['member_pass']) {
if ($this->checkLogin($_SESSION['member_name'], $_SESSION['member_pass'])) {
$sRule = $this->aMembers[$_SESSION['member_name']]['rule'];
$sPermissions = '';
$sPermissions .= $this->isCanRead($sRule);
$sPermissions .= $this->isCanCreate($sRule);
$sPermissions .= $this->isCanEdit($sRule);
$sPermissions .= $this->isCanEditAny($sRule);
$sPermissions .= $this->isCanDelete($sRule);
$sPermissions .= $this->isCanDeleteAny($sRule);
ob_start(); // get template of Logout form
require_once('logout_form.html');
$sLogoutForm = ob_get_clean();
$sLogoutForm = str_replace('{name}', $_SESSION['member_name'], $sLogoutForm);
$sLogoutForm = str_replace('{bit_mask}', $sRule, $sLogoutForm);
$sLogoutForm = str_replace('{possibilities}', $sPermissions, $sLogoutForm);
return $sLogoutForm;
}
}
// otherwise - draw login form
ob_start();
require_once('login_form.html');
$sLoginForm = ob_get_clean();
return $sLoginForm;
}
}
// check functions
function isCanRead($sRule) {
return ($sRule & CAN_READ) ? 'You can Read<br />' : '';
}
function isCanCreate($sRule) {
return ($sRule & CAN_CREATE) ? 'You can Create<br />' : '';
}
function isCanEdit($sRule) {
return ($sRule & CAN_EDIT_OWN) ? 'You can Edit<br />' : '';
}
function isCanEditAny($sRule) {
return ($sRule & CAN_EDIT_ANY) ? 'You can Edit anything<br />' : '';
}
function isCanDelete($sRule) {
return ($sRule & CAN_DELETE_OWN) ? 'You can Delete<br />' : '';
}
function isCanDeleteAny($sRule) {
return ($sRule & CAN_DELETE_ANY) ? 'You can Delete anything<br />' : '';
}
// perform login
function performLogin($sName, $sPass) {
$this->performLogout();
$sSalt = $this->aMembers[$sName]['salt'];
$sPass = sha1(md5($sPass) . $sSalt);
$_SESSION['member_name'] = $sName;
$_SESSION['member_pass'] = $sPass;
}
// perform logout
function performLogout() {
unset($_SESSION['member_name']);
unset($_SESSION['member_pass']);
}
// check login
function checkLogin($sName, $sPass, $isHash = true) {
if (isset($this->aMembers[$sName])) {
if (! $isHash) {
$sSalt = $this->aMembers[$sName]['salt'];
$sPass = sha1(md5($sPass) . $sSalt);
}
return ($sPass == $this->aMembers[$sName]['hash']);
}
return false;
}
}
First, we define the constants for access rights (bit mask). Further, when we enumerate users on the system – we grant them different sets of rights (using the logical operator | or). Keep in mind that I am not forcing you to keep users in the same array, in your case, your users can easily be in the database. And, in this case, you can grant them their right in the database itself. Further, I have added extra check functions, so that we can understand if user can perform a certain action.
首先,我们定义访问权限的常量(位掩码)。 此外,当我们枚举系统上的用户时,我们会授予他们不同的权限集(使用逻辑运算符|或)。 请记住,我并没有强迫您将用户保持在同一阵列中,在这种情况下,您的用户可以轻松地位于数据库中。 并且,在这种情况下,您可以在数据库本身中授予他们权利。 此外,我添加了额外的检查功能,以便我们了解用户是否可以执行某些操作。
In such functions we use logic operator & (and). Most of these checks uses single bit check. If you want to make multiple check, as example – lets create function to check if member can read and create. Then this function will looks like this:
在此类函数中,我们使用逻辑运算符&(和)。 这些检查大多数使用单位检查。 例如,如果您要进行多次检查–让create函数检查成员是否可以读取和创建。 然后,此函数将如下所示:
function isCanReadCreate($sRule) {
return ($sRule & (CAN_READ | CAN_CREATE));
}
function isCanReadCreate($sRule) {
return ($sRule & (CAN_READ | CAN_CREATE));
}
This function will return us True or False.
此函数将返回True或False。
现场演示
存档下载
结论 (Conclusion)
I hope that it was interesting for you to remember how works bitwise and logical operands. If you have any good ideas you would like to share, be sure to write us as well. Good luck!
我希望您能记住按位和逻辑操作数的工作方式很有趣。 如果您有什么好想法要分享,请务必也写信给我们。 祝好运!
翻译自: https://www.script-tutorials.com/access-control-with-bit-masks/