API Overview
Tổng quan này chỉ cho bạn cách sử dụng các API của Casbin và không giải thích cách Casbin được cài đặt hoặc nó hoạt động như thế nào. Bạn có thể tìm thấy các hướng dẫn đó tại đây: Cài đặt Casbin và Cách Casbin Hoạt Động. Vì vậy, khi bạn bắt đầu đọc hướng dẫn này, chúng tôi giả định rằng bạn đã cài đặt đầy đủ và nhập Casbin vào mã của mình.
Thực thi API
Hãy bắt đầu với các API Thực thi của Casbin. Chúng ta sẽ tải một mô hình RBAC từ model.conf
và tải các chính sách từ policy.csv
. Bạn có thể tìm hiểu về cú pháp Mô hình tại đây, và chúng tôi sẽ không thảo luận về nó trong hướng dẫn này. Chúng tôi giả định rằng bạn có thể hiểu các tệp cấu hình được cung cấp dưới đây:
model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
policy.csv
p, admin, data1, read
p, admin, data1, write
p, admin, data2, read
p, admin, data2, write
p, alice, data1, read
p, bob, data2, write
g, amber, admin
g, abc, admin
Sau khi đọc các tệp cấu hình, hãy đọc đoạn mã sau.
// Load information from files.
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
log.Fatalf("Error, detail: %s", err)
}
ok, err := enforcer.Enforce("alice", "data1", "read")
Đoạn mã này tải mô hình kiểm soát truy cập và các chính sách từ các tệp cục bộ. Hàm casbin.NewEnforcer()
sẽ trả về một enforcer. Nó sẽ nhận ra hai tham số của nó là đường dẫn tệp và tải các tệp từ đó. Lỗi xảy ra trong quá trình này được lưu trữ trong biến err
. Đoạn mã này sử dụng bộ điều hợp mặc định để tải mô hình và chính sách, và tất nhiên, bạn có thể đạt được kết quả tương tự bằng cách sử dụng bộ điều hợp của bên thứ ba.
Đoạn mã ok, err := enforcer.Enforce("alice", "data1", "read")
được sử dụng để xác nhận quyền truy cập. Nếu Alice có thể truy cập data1 với thao tác đọc, giá trị trả về của ok
sẽ là true
; ngược lại, nó sẽ là false
. Trong ví dụ này, giá trị của ok
là true
.
EnforceEx API
Đôi khi bạn có thể tự hỏi chính sách nào đã cho phép yêu cầu, vì vậy chúng tôi đã chuẩn bị hàm EnforceEx()
. Bạn có thể sử dụng nó như thế này:
ok, reason, err := enforcer.EnforceEx("amber", "data1", "read")
fmt.Println(ok, reason) // true [admin data1 read]
Hàm EnforceEx()
sẽ trả về chuỗi chính sách chính xác trong giá trị trả về reason
. Trong ví dụ này, amber
là vai trò admin
, vì vậy chính sách p, admin, data1, read
cho phép yêu cầu này trở thành true
. Đầu ra của đoạn mã này được thể hiện trong chú thích.
Casbin đã cung cấp nhiều API tương tự như thế này. Những API này thêm một số chức năng bổ sung vào các chức năng cơ bản. Chúng bao gồm:
ok, err := enforcer.EnforceWithMatcher(matcher, request)
Hàm này sử dụng một matcher.
ok, reason, err := enforcer.EnforceExWithMatcher(matcher, request)
Đây là sự kết hợp của
EnforceWithMatcher()
vàEnforceEx()
.boolArray, err := enforcer.BatchEnforce(requests)
Chức năng này cho phép một danh sách các công việc và trả về một mảng.
Đây là một trường hợp sử dụng đơn giản của Casbin. Bạn có thể sử dụng Casbin để bắt đầu một máy chủ ủy quyền sử dụng các API này. Chúng tôi sẽ chỉ cho bạn một số loại API khác trong các đoạn văn sau đây.
API Quản lý
API Lấy
Các API này được sử dụng để lấy các đối tượng cụ thể trong các chính sách. Trong ví dụ này, chúng tôi đang tải một enforcer và lấy một cái gì đó từ nó.
Xin vui lòng xem xét đoạn mã sau:
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
allSubjects := enforcer.GetAllSubjects()
fmt.Println(allSubjects)
Tương tự như ví dụ trước, bốn dòng đầu tiên được sử dụng để tải thông tin cần thiết từ các tệp cục bộ. Chúng tôi sẽ không thảo luận vấn đề đó ở đây thêm nữa.
Mã allSubjects := enforcer.GetAllSubjects()
lấy tất cả các chủ thể trong tệp chính sách và trả về chúng dưới dạng một mảng. Sau đó, chúng tôi in mảng đó.
Thông thường, đầu ra của mã nên là:
[admin alice bob]
Bạn cũng có thể thay đổi hàm GetAllSubjects()
thành GetAllNamedSubjects()
để lấy danh sách các chủ thể xuất hiện trong chính sách được đặt tên hiện tại.
Tương tự, chúng tôi đã chuẩn bị các hàm GetAll
cho Objects, Actions, Roles
. Để truy cập các hàm này, bạn chỉ cần thay thế từ Subject
trong tên hàm bằng danh mục mong muốn.
Ngoài ra, còn có nhiều getter khác có sẵn cho các chính sách. Phương thức gọi và giá trị trả về tương tự như những cái đã được đề cập ở trên.
policy = e.GetPolicy()
lấy tất cả các quy tắc ủy quyền trong chính sách.filteredPolicy := e.GetFilteredPolicy(0, "alice")
lấy tất cả các quy tắc ủy quyền trong chính sách với các bộ lọc trường được chỉ định.namedPolicy := e.GetNamedPolicy("p")
lấy tất cả các quy tắc ủy quyền trong chính sách được đặt tên.filteredNamedPolicy = e.GetFilteredNamedPolicy("p", 0, "bob")
lấy tất cả các quy tắc ủy quyền trong chính sách được đặt tên với các bộ lọc trường được chỉ định.groupingPolicy := e.GetGroupingPolicy()
lấy tất cả các quy tắc thừa kế vai trò trong chính sách.filteredGroupingPolicy := e.GetFilteredGroupingPolicy(0, "alice")
lấy tất cả các quy tắc thừa kế vai trò trong chính sách với các bộ lọc trường được chỉ định.namedGroupingPolicy := e.GetNamedGroupingPolicy("g")
lấy tất cả các quy tắc thừa kế vai trò trong chính sách.namedGroupingPolicy := e.GetFilteredNamedGroupingPolicy("g", 0, "alice")
lấy tất cả các quy tắc thừa kế vai trò trong chính sách với các bộ lọc trường được chỉ định.
Thêm, Xóa, Cập nhật API
Casbin cung cấp nhiều API để thêm, xóa hoặc sửa đổi chính sách một cách linh hoạt trong thời gian chạy.
Đoạn mã sau đây minh họa cách thêm, xóa và cập nhật chính sách, cũng như cách kiểm tra xem một chính sách có tồn tại hay không:
// load information from files
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
// add a policy and use HasPolicy() to confirm
enforcer.AddPolicy("added_user", "data1", "read")
hasPolicy := enforcer.HasPolicy("added_user", "data1", "read")
fmt.Println(hasPolicy) // true, the policy was added successfully
// remove a policy and use HasPolicy() to confirm
enforcer.RemovePolicy("alice", "data1", "read")
hasPolicy = enforcer.HasPolicy("alice", "data1", "read")
fmt.Println(hasPolicy) // false, the policy was removed successfully
// update a policy and use HasPolicy() to confirm
enforcer.UpdatePolicy([]string{"added_user", "data1", "read"}, []string{"added_user", "data1", "write"})
hasPolicy = enforcer.HasPolicy("added_user", "data1", "read")
fmt.Println(hasPolicy) // false, the original policy has expired
hasPolicy = enforcer.HasPolicy("added_user", "data1", "write")
fmt.Println(hasPolicy) // true, the new policy is in effect
Bằng cách sử dụng các API này, bạn có thể chỉnh sửa các chính sách của mình một cách linh hoạt. Tương tự, chúng tôi đã cung cấp các API tương tự cho FilteredPolicy, NamedPolicy, FilteredNamedPolicy, GroupingPolicy, NamedGroupingPolicy, FilteredGroupingPolicy, FilteredNamedGroupingPolicy
. Để sử dụng chúng, chỉ cần thay thế từ Policy
trong tên hàm bằng danh mục thích hợp.
Hơn nữa, bằng cách thay đổi các tham số thành mảng, bạn có thể thực hiện chỉnh sửa hàng loạt các chính sách của mình.
Ví dụ, hãy xem xét các hàm như thế này:
enforcer.UpdatePolicy([]string{"eve", "data3", "read"}, []string{"eve", "data3", "write"})
Nếu chúng ta thay đổi Policy
thành Policies
và sửa đổi các tham số như sau:
enforcer.UpdatePolicies([][]string{{"eve", "data3", "read"}, {"jack", "data3", "read"}}, [][]string{{"eve", "data3", "write"}, {"jack", "data3", "write"}})
sau đó chúng ta có thể thực hiện chỉnh sửa hàng loạt các chính sách này.
Các thao tác tương tự cũng có thể áp dụng cho GroupingPolicy, NamedGroupingPolicy
.
API AddEx
Casbin cung cấp dãy API AddEx để giúp người dùng thêm các quy tắc theo lô.
AddPoliciesEx(rules [][]string) (bool, error)
AddNamedPoliciesEx(ptype string, rules [][]string) (bool, error)
AddGroupingPoliciesEx(rules [][]string) (bool, error)
AddNamedGroupingPoliciesEx(ptype string, rules [][]string) (bool, error)
SelfAddPoliciesEx(sec string, ptype string, rules [][]string) (bool, error)
Sự khác biệt giữa các phương pháp này và các phương pháp không có hậu tố Ex là nếu một trong các quy tắc đã tồn tại, chúng sẽ tiếp tục kiểm tra quy tắc tiếp theo thay vì trả về false ngay lập tức.
Ví dụ, hãy so sánh AddPolicies
và AddPoliciesEx
.
Bạn có thể chạy và quan sát mã nguồn sau bằng cách sao chép nó vào bài kiểm tra trong casbin.
func TestDemo(t *testing.T) {
e, err := NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
e.ClearPolicy()
e.AddPolicy("user1", "data1", "read")
fmt.Println(e.GetPolicy())
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}})
// policy {"user1", "data1", "read"} now exists
// Use AddPolicies to add rules in batches
ok, _ := e.AddPolicies([][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
fmt.Println(e.GetPolicy())
// {"user2", "data2", "read"} failed to add because {"user1", "data1", "read"} already exists
// AddPolicies returns false and no other policies are checked, even though they may not exist in the existing ruleset
// ok == false
fmt.Println(ok)
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}})
// Use AddPoliciesEx to add rules in batches
ok, _ = e.AddPoliciesEx([][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
fmt.Println(e.GetPolicy())
// {"user2", "data2", "read"} is added successfully
// because AddPoliciesEx automatically filters the existing {"user1", "data1", "read"}
// ok == true
fmt.Println(ok)
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
}
RBAC API
Casbin cung cấp một số API cho bạn để sửa đổi mô hình và chính sách RBAC. Nếu bạn quen thuộc với RBAC, bạn có thể dễ dàng sử dụng các API này.
Ở đây, chúng tôi chỉ chỉ cho bạn cách sử dụng các API RBAC của Casbin và sẽ không nói về RBAC nói chung. Bạn có thể tìm thêm chi tiết tại đây.
Chúng tôi sử dụng mã nguồn sau để tải mô hình và chính sách, giống như trước đây.
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
Sau đó, chúng ta có thể sử dụng một thể hiện của Enforcer enforcer
để truy cập các API này.
roles, err := enforcer.GetRolesForUser("amber")
fmt.Println(roles) // [admin]
users, err := enforcer.GetUsersForRole("admin")
fmt.Println(users) // [amber abc]
GetRolesForUser()
trả về một mảng chứa tất cả các vai trò mà amber có. Trong ví dụ này, amber chỉ có một vai trò, đó là admin, vì vậy mảng roles
là [admin]
. Tương tự, bạn có thể sử dụng GetUsersForRole()
để lấy danh sách người dùng thuộc một vai trò. Giá trị trả về của hàm này cũng là một mảng.
enforcer.HasRoleForUser("amber", "admin") // true
Bạn có thể sử dụng HasRoleForUser()
để xác nhận xem người dùng có thuộc vai trò đó hay không. Trong ví dụ này, amber là thành viên của admin, vì vậy giá trị trả về của hàm là true
.
fmt.Println(enforcer.Enforce("bob", "data2", "write")) // true
enforcer.DeletePermission("data2", "write")
fmt.Println(enforcer.Enforce("bob", "data2", "write")) // false
Bạn có thể sử dụng DeletePermission()
để xóa một quyền.
fmt.Println(enforcer.Enforce("alice", "data1", "read")) // true
enforcer.DeletePermissionForUser("alice", "data1", "read")
fmt.Println(enforcer.Enforce("alice", "data1", "read")) // false
Và sử dụng DeletePermissionForUser()
để xóa một quyền cho một người dùng.
Casbin có nhiều API như thế này. Cách gọi và giá trị trả về của chúng có cùng kiểu như các API trên. Bạn có thể tìm thấy các API này trong tài liệu tiếp theo.