Kỹ thuật bit field trong phân quyền
Bài viết này sẽ hướng dẫn cho các bạn áp dụng kỹ thuật bit field trong phân quyền chức năng ứng dụng.
Mở đầu
Ý tưởng là dùng các bit để lưu trạng thái, hoặc phân quyền trong chương trình. Với cách lưu này thì mỗi trạng thái chỉ tốn 1 bit để lưu trữ. Vi dụ ta lưu 4 quyền view/add/edit/delete theo một dãy 0-1, được lưu trong một biến kiểu int. [Với kiểu int32 ta có thể lưu tối đa 32 trạng thái].
Full control [15]:
Delete | Edit | Add | View |
1 | 1 | 1 | 1 |
Tương ứng, ta lưu các quyền với các giá trị như sau:
Base | Delete | Edit | Add | View |
Tương ứng, ta lưu các quyền với các giá trị như sau: | 1000 | 100 | 10 | 1 |
Base | Binary | Bitwise | 1 < 3 | 1 < 2 |
1 < 1 | 8 | 4 | 2 | 1 |
1 < 0
Decimal
view + add = 1 + 2 = 3
view + add + edit = 1 + 2 + 4 = 7
view + add + edit + delete = 1 + 2 + 4 + 8 = 15
Bây giờ ta có các quyền được thể hiện như sau:
view = 1 view + add = 1 + 2 = 3 view + add + edit = 1 + 2 + 4 = 7 view + add + edit + delete = 1 + 2 + 4 + 8 = 15
Chẳng hạn khi cần kiểm tra user có quyền edit hay không, ta chỉ cần lấy quyền của user và AND với giá trị edit [4] nếu nó khác 0 [và bằng chính quyền đó, trong trường hơp edit là 4] là user có quyền thực hiện quyền này.
Delete | Edit | Add | View |
0 | 1 | 1 | 1 |
Delete | Edit | Add | View |
0 | 0 | 1 | 1 |
Delete | Edit | Add | View |
0 | 0 | 0 | 1 |
Tương ứng, ta lưu các quyền với các giá trị như sau:
Base
Binary
- Thêm tin
- Xóa tin
- Sửa tin
Bitwise
1 < 3
- $bitfields_news = array[
- 'canview' => 1, 'canview' => 1,
- 'canadd' => 2, 'canadd' => 2,
- 'canedit' => 4, 'canedit' => 4,
- 'candelete' => 8]; 'candelete' => 8];
1 < 2
1 < 1
1 < 0
Decimal
Bây giờ ta có các quyền được thể hiện như sau:
view = 1 view + add = 1 + 2 = 3 view + add + edit = 1 + 2 + 4 = 7 view + add + edit + delete = 1 + 2 + 4 + 8 = 15
Chẳng hạn khi cần kiểm tra user có quyền edit hay không, ta chỉ cần lấy quyền của user và AND với giá trị edit [4] nếu nó khác 0 [và bằng chính quyền đó, trong trường hơp edit là 4] là user có quyền thực hiện quyền này.
Bảng các quyền tương ứng với cơ số 10:
1_____admin______15
2_____editor______5
Edit-Add-View [7]
- if [$users['Group']['news_permission'] & 8] { [$users['Group']['news_permission'] & 8] {
- }
Ví dụ
Giả sử module tin tức trong ứng dụng của mình có 4 chức năng:
- decbin[15] = 1111
- decbin[8] = 1000
- Đọc tin - Thêm tin - Xóa tin - Sửa tin
Mình cần phân quyền cho 2 nhóm: admin và editor
- Áp dụng kỹ thuật bit field, mình sẽ cho mỗi chức năng của module tin tức 1 con số đại diện, và lưu thành mảng:
- class bitmask bitmask
- {
- public $permissions = array[ public $permissions = array[
- "read"=>false, "read"=>false,
- "write"=>false, "write"=>false,
- "delete"=>false, "delete"=>false,
- "change_permissions"=>false, "change_permissions"=>false,
- "admin"=>false "admin"=>false
- ];
- publicfunction getPermissions[$bitMask =0]
- {
- $i =0;
- foreach[$this->permissions as $key => $value] foreach[$this->permissions as $key => $value]
- {
- $this->permissions[$key]=[[$bitMask & pow[2, $i]]!=0]?true:false; this->permissions[$key]=[[$bitMask & pow[2, $i]]!=0]?true:false;
- $i++;
- }
- return $this->permissions; return $this->permissions;
- }
- function toBitmask[]
- {
- $bitmask =0;
- $i =0;
- foreach[$this->permissions as $key => $value] foreach[$this->permissions as $key => $value]
- {
- if[$value] if[$value]
- {
- $bitmask += pow[2, $i];
- }
- $i++;
- }
- return $bitmask; return $bitmask;
- }
- }
- ?>
Lưu vào cơ sở dữ liệu:
Xuất giá trị: