-
Thiết kế Ctrình phân quyền
Noname > 15-08-10, 01:48 PM
Phân quyền trong Access
Trong Access đã hỗi trợ phân quyền bằng cách tạo file workGroup *.mdw, *.mda. tuy nhiên cách này hơi nhiêu khê ở chỗ là máy sử dụng phải map tới file này thì mới xài được.
Vì vậy một cách khác mọi người quan tâm là phân quyền trực tiếp trong chương trình access của mình. Nếu mình post 1 đoạn chương trình lên cho mọi người tham khảo thì quá dễ dàng, nhưng điều đó không mang ý nghĩa học tập. Vì vậy, mình quyết định sẽ tiến hành Phân tích bài toán và thiết lập từng bước sao cho dễ hiểu nhất, ai biết Access cũng có thể làm được.
I/Mô tả:
Chương trình sẽ yêu cầu đăng nhập mỗi khi mở, nếu không có user name thì chỉ vào được quyền hạn chế dành cho khách.
II/ Thiết kế và giải thuật:
Mô tả ý tưởng:
- Khi bạn đăng nhập vào, chương trình sẽ ghi nhận username của bạn trong một biến toàn cục(public).
Sau đó sẽ qua một function để biết bạn thuộc group nào.( mình chia group thành các cấp khác nhau, cấp cao thì quyền nhiều hơn cấp dưới)
- Ở mỗi process cụ thể sẽ cho biết cấp tối thiểu để được đăng nhập vào process đó.
Chuẩn bị table:
- Table cần có là danh sách user: tblDSUser(ID,pass)
- Table lưu cấp của các user: tblWorkGroup(WgLevel, WgName,user)
Trong đó : username là khóa ngoại liên kết với tblDSUser
Dữ liệu nhập thử:
tblDSUser
ID --- Pass
Admin ---- Admin
Duytuan ---- tuan
Guest ----
tblWorkGroup
WGLevel---WgName---User
9---Admin --- Admin
8---User --- Duytuan
0---Guest---guest
Việc đều tiên là bạn vào khai báo một biến toàn cục tên là user, cách làm như sau:
Vào menu Tool => marcr Visual basic editor
Một cửa sổ VB xuất hiện, tại đây bạn vào menu Inser => module
Trong Module mới tạo, bạn khai báo một biến toàn cục để lưu tên user hiện hành:
Mã:Public username as string
OK, bây giờ bạn đã đủ đồ nghề để tạo form đăng nhập.
Đầu tiên, bạn tạo 1 form, đặt tên nó là frmLogin
1/Vẽ 1 lable với caption như sau “Xin mời nhập Username,pass hoặc nhấn vào guest để ghé thử”
2/Vẽ 1 combobox đặt tên là: cbbusername,
thuộc tính row source: SELECT tblDSUser.ID, tblDSUser.Pass FROM tblDSUser;
3/ Vẽ một textbox đặt tên là txtPassWord
Input mask kiểu Password
4/ Vẽ 1 text box đặt tên là txtPassTemp
Thuộc tính visible là No
5/ vẽ một nút đặt tên là cmdLogin
6/Vẽ một nút đặt tên là cmdGuest
Vậy là xong phần giao diện, bây giờ là cái ruột
Mô tả:
Sau khi cập nhật tên user thì txtPassTemp sẽ lấy về cái password , và field này user hoàn toàn không nhìn thấy. Mục đích là để so sánh pass này với cái pass của user nhập vào. Đúng thì tiếp tục log vào form chính, đồng thời gán biến username bằng tên đăng nhập, sai thì báo lỗi.
Như vậy, hành động after Update của ComboBox nhập user như sau:
Trích:
Mã:Private Sub cbbUsername_AfterUpdate()
Me.txtPassTemp.Value = cbbUserName.Column(1)
‘ lấy về password
End Sub
Bây giờ ta xử lý nút Login,
đầu tiên bạn khoan đã xử. Bạn tạo 1 form đặt tên là frmMain rồi chừa trống đấy, form này để dành sau khi login thì nó sẽ gọi lên.
Bây giờ ta quay lại với nút login.
Nó phải làm các việc sau:+
- Kiểm tra password nhập vào có đúng với field : txtPassTemp hay không, nếu đúng thì làm cái việc là gán biến toàn cục username bằng giá trị của ô CbbUsername.
- Chào mừng user đó đăng nhập
- Mở form frmMain
- Đóng form frmLogin lại
Nếu sai thì báo là nhập sai
Đoạn code xử lý như sau:
Trích:
Bây giờ tới nút cmdGuestMã:Private Sub cmdLogin_Click()
If Me.txtPassWord.Value = Me.txtPassTemp.Value Then
Username = Me.cbbUserName
MsgBox "Welcom To " & Username
DoCmd.OpenForm "frmMain"
DoCmd.Close acForm, "frmLogin"
Else
MsgBox "Login Fail, check your Username and your password"
End If
End Sub
Tương tự nhưng không cần kiểm tra gì cả, tên username được gán bằng tên Guest và vào thẳng form main
Trích:
Mã:Private Sub CmdGuest_Click()
Username = "Guest"
MsgBox "Welcom To " & Username
DoCmd.OpenForm "frmMain"
DoCmd.Close acForm, "frmLogin"
End Sub
Trong khi chờ đợi các bạn cứ thiết kế Main form như hình nhé, nội dung thì thứ 2 No lên phân tích tiếp
Hôm trước mình nhầm lẫn một chút ở khâu chuẩn bị table
Trích:
sai ở table tblWorkGroup, vì như vậy thì ở mỗi level ta chỉ tạo được một user thôiMã:Chuẩn bị table:
- Table cần có là danh sách user: tblDSUser(ID,pass)
- Table lưu cấp của các user: tblWorkGroup(WgLevel, WgName,user)
Trong đó : username là khóa ngoại liên kết với tblDSUser
Mình xin đính chính lại table này
Mã:tblWorkGroup(WgLevel, WgName,user)
Đầu tiên, để chuẩn bị cái ruột cho mainform, chúng ta phải có một đoạn code để lấy về level của user hiện hành.
Các bạn còn nhớ cái module mà bạn đã khai báo biến toàn cục: username chứ?
bây giờ mở nó lên, viết tiếp vào đoạn code lấy về level user
Trích:
OK, bây giờ đồ nghề đầy đủ, các bạn vẽ mainform rồi chứ/? Đặt tên cái form đó là frmMain.Mã:Function checkuser() As Integer
On Error GoTo Err ' nếu user vào trực tiếp bằng quyền guest thì cho level là 0
Dim rs1 As Recordset
Dim sql As String
sql = " select max(WGlevel) from tblWorkGroup where user= '" & Username & "'"
Set rs1 = CurrentDb.OpenRecordset(sql)
rs1.MoveFirst
checkuser = rs1(0).Value
Exit Function
Err:
checkuser = 0
Exit Function
End Function
Các nút trên form đặt tên lần lượt là: cmdAdmin,cmdUser,cmdGuest
Trong chương trình của mình sẽ chia làm 9 cấp độ đăng nhập, quyền cao nhất Admin,sẽ vào với level 9, các user tùy theo là trưởng phòng hay nhân viên sẽ có level 1-8
Guest sẽ vào với level 0. Giải thuật của ta ứng với mỗi nút là sẽ tạo ra yêu cầu level tối thiểu. Đối với user Admin thì tối thiểu phải level 9
OK.
Bây giờ ta xử lý nút cmd Admin như sau
Trích:
Tương tự với Nút user, ở ví dụ này, nút user yêu cầu phải level 8 mới vào được. bạn có thể hạ thấp level yêu cầu xuống cho nhân viên.Mã:Private Sub cmdAdmin_Click()
Dim userRequest As String ‘ biến yêu cầu user tối thiểu
userRequest = 9
If userRequest <= checkuser Then
MsgBox "Xin chao ban đa dang nhap vao quyen admin"
Else
MsgBox "ban khonn duoc dang nhap function nay"
End If
End Sub
Trích:
Và nút guest cũng tương tựMã:Private Sub cmdUser_Click()
Dim userRequest As String
userRequest = 8
If userRequest <= checkuser Then
MsgBox "Xin chao ban da dang nhap vao quyen user"
Else
MsgBox "ban khong duoc dang nhap function nay"
End If
End Sub
Trích:
Hihi, đáng lẽ có thể sửa quyền khách cho hợp lý hơn, nhưng mình copy paster cho nhanhMã:Private Sub CmdGuest_Click()
Dim userRequest As String
userRequest = 0
If userRequest <= checkuser Then
MsgBox "Xin chao dang nhap vao quyen khach"
Else
MsgBox "ban khogn duoc dang nhap function nay"
End If
End Sub
Hướng dẫn cơ bản tương đối ổn rồi, bây giờ ta “ màu mè” một chút là khi vào chương trình bắt buột phải login vào cái frmLogin, cách nào ư? Nhiều lắm, nhưng mình thích dùng cái marcro.
Bạn tạo một marcro, đặt tên nó là AutoExec
Thằng này sẽ tự chạy mỗi khi ta vào chương trình.
Nội dung của marcro AutoExec chỉ có 1 hành động dòng như sau:
Open form
Form name: frmLogin
View: form
Windows mode: Dialog
Sở dĩ tôi bảo các bạn dùng marcro là vì cái Dialog này, nó bắt buột phải đăng nhập mới vào, còn không thì nhấn guest.
Sau đó ta vào menu Tool =>startup bỏ chọn hết tất cả để nó không cho các user táy máy khi đăng nhập.
Chưa xong đâu, bạn quay lại cái Module, mở nó lên, vào menu Tool => “tên chương trình” properties nhảy qua tab protection, cài password cho cái source của bạn luôn. Cho mấy tay táy máy khỏi link vào import mấy cái table quý hóa của mình.
OK.
Đóng chương trình và mở lại. Thử với các quyền thử xem!
Và bây giờ bạn muốn edit chương trình thì làm thế nào? Dễ thôi! Nhấn phím shift trong khi mở nó sẽ không load macro AutoExec nữa, vào cửa sổ design như bình thường!
Vậy chương trình không an toàn về bảo mật? Ồ không đâu, tôi sẽ giới thiệu trong bài khác về cách vô hiệu hóa phím shift, và khi muốn mở lại thì phải Enable phím shift
Nếu các bạn chưa tin về tính bảo mật? Hãy thử chương trình Demo của Noname xem! trừ khi bạn đăng nhập vào quyền admin, còn lại các user kia thì không sửa xóa gì chương trình được cả
http://duyeagle.googlepages.com/phanquyen.rar
-
RE: Thiết kế Ctrình phân quyền
Noname > 15-08-10, 01:48 PM
Dưới đây và 1 ví dụ demo về phân quyền của bạn Haquocquan, cũng rất hay đáng để ta tham khảo>
Pass như sau:
Khi đăng nhập:
- User: QUAN ---- Password: ladieskiller
- Các user khác: password: 123
Còn khi vào các mục khác có yêu cầu password: ladieskiller
http://sites.google.com/site/thuvienthut...ects=0&d=1 -
RE: Thiết kế Ctrình phân quyền
ncxn > 13-09-10, 05:47 PM
hì hì, hổng có chương trình gì mà login vô có dzụ Admin, user và guest é. Ngừ ta chỉ làm txtPass và txtUser và cmdLogin , nếu chương trình lớn hơn thì thêm cái cbox để chọn database
-----------
Về yêu cầu phân quyền ứng dụng thì ông suy nghĩ theo hướng này nà:
1. Tập hợp toàn bộ các ứng đối tượng trong chương trình( form, report, query, table) và các thuộc tính do người viết chương trình định nghĩa: xem, thêm, sửa, xóa . Đó là cái cơ bản nhất khi muốn viết hệ thống phân quyền
2. Lập luận rằng mỗi một user khi vào chương trình được cấp cho các thuộc tính tương ứng với đối tượng nào đó thôi
ví dụ: userA được quyền xem, thêm, sửa fromX thì khi user này login vào ( cấp cho nó cái biến toàn cục currentUser = userA) khi đó chương trình sẽ tạo ra tem_Query (query có hiệu lực khi user còn hoạt động trên Clien) có dạng userA(FormX, xem=true, thêm= true, sửa = true, xóa=false)
3. Khi đó ta tạo một function (curentUser) để xử lý các thuộc tính xem, sửa, thêm, xóa là xong . Chú ý rằng function này viết dựa trên cái tem_Query kia là được.
-----------
hì hì,mình cũng chưa làm lần nào nhưng thấy các chương trình họ đều làm theo hướng này -
RE: Thiết kế Ctrình phân quyền
Noname > 13-09-10, 08:47 PM
(13-09-10, 05:47 PM)ncxn Đã viết: hì hì, hổng có chương trình gì mà login vô có dzụ Admin, user và guest é. Ngừ ta chỉ làm txtPass và txtUser và cmdLogin , nếu chương trình lớn hơn thì thêm cái cbox để chọn database
-----------
Về yêu cầu phân quyền ứng dụng thì ông suy nghĩ theo hướng này nà:
1. Tập hợp toàn bộ các ứng đối tượng trong chương trình( form, report, query, table) và các thuộc tính do người viết chương trình định nghĩa: xem, thêm, sửa, xóa . Đó là cái cơ bản nhất khi muốn viết hệ thống phân quyền
2. Lập luận rằng mỗi một user khi vào chương trình được cấp cho các thuộc tính tương ứng với đối tượng nào đó thôi
ví dụ: userA được quyền xem, thêm, sửa fromX thì khi user này login vào ( cấp cho nó cái biến toàn cục currentUser = userA) khi đó chương trình sẽ tạo ra tem_Query (query có hiệu lực khi user còn hoạt động trên Clien) có dạng userA(FormX, xem=true, thêm= true, sửa = true, xóa=false)
3. Khi đó ta tạo một function (curentUser) để xử lý các thuộc tính xem, sửa, thêm, xóa là xong . Chú ý rằng function này viết dựa trên cái tem_Query kia là được.
-----------
hì hì,mình cũng chưa làm lần nào nhưng thấy các chương trình họ đều làm theo hướng này
Như ý của bạn cũng hay, và mình cũng làm rồi, vài hệ thống lớn người ta cũng làm rồi! Ưu điểm là dễ thiết kế.
Khuyết điểm nếu công ty bạn có nhiều user, nhiều nhóm user thì làm vậy người quản trị sẽ tốn nhiều thời gian cho mỗi người. Trong khi đó nếu phân quyền theo group, thì bạn chỉ việc gán user đó cho 1 group, và quyền hạn là quyền bạn cấp cho group đó. Bằng chứng là hệ thống user của diễn đàn này và cách cấp phát user của Windows. (nếu bạn làm với file server không thể không biết chức năng này).
Cái này mình chỉ hướng dẫn theo cách cơ bản nhất. Quan trọng là ở giải thuật. Và khi làm được thì có thể tự phát triển theo hướng riêng mình!
Thân!
-
RE: Thiết kế Ctrình phân quyền
ncxn > 14-09-10, 10:46 AM
Group thì chỉ cần viết cái function kia dành cho Group rồi add user vào Group là được.
Lúc này User sẽ thừa hưởng toàn bộ các quyền được cấp cho Group , hơn nữa 1 user có thể nằm trong nhiều Group (kiêm nhiệm) và có thể không nằm trong Gr nào nhưng vẫn được cấp quyền sử dụng
Cái này có lợi thế là : người quản trị có thể tạo luôn group -- cấp quyền cho nó xong rồi tạo user add vào group là xong
------Hì hì cái ncxn muốn làn người dùng có thể thao tác hoàn toàn chứ không làm sẵn cố định một chức năng nào. (Trừ khi điều đó là bắt buộc)
ncnx cũng mới tìm hiểu về access nhưng xem ra hạn chế cũng không nhỏ nhỉ.
Đang mò cái vụ menu : suy nghĩ thế này
Tạo một table chứa dữ liệu các menu
tblMenu(ID, level, name, label, object, object_type, action, action_type, enable)
- level:
----1
------11
------12
----------121
----------122
-----2
... Nói chung thuật toán này cũng không khó
- name, label : thì chỉ là tên của nó thôi
- object, object_type : ví dụ fromA thì type là from
- action, action_type : ví dụ fromA có action là click và type là view (chẳn hạn nếu report thì cho print luôn)
- enable (true/false): nếu true thì user được cấp quyền sẽ thấy menu này (field này sẽ update theo bản phân quyền của user khi user login vào chương trình). True: cho hiện menu/ false: ngược lại
---------
Mấy cái object, type sẽ tự động tập hợp khi user tạo menu mới
---------
Đó như vậy người dùng cũng có thể tạo/xóa menu cho riêng mình hìhi
Khả thi không nhỉ -
RE: Thiết kế Ctrình phân quyền
Noname > 14-09-10, 11:25 AM
(14-09-10, 10:46 AM)ncxn Đã viết: Group thì chỉ cần viết cái function kia dành cho Group rồi add user vào Group là được.
Vấn đề không phải là ở Access mà là ở giải thuật. Nếu chỉ thao tác thuần túy trên dữ liệu thì mình nghĩ Access rất nhanh và mạnh rồi! (còn bảo mật thì đành nhờ bác SQL server làm back-end thôi
Lúc này User sẽ thừa hưởng toàn bộ các quyền được cấp cho Group , hơn nữa 1 user có thể nằm trong nhiều Group (kiêm nhiệm) và có thể không nằm trong Gr nào nhưng vẫn được cấp quyền sử dụng
Cái này có lợi thế là : người quản trị có thể tạo luôn group -- cấp quyền cho nó xong rồi tạo user add vào group là xong
------Hì hì cái ncxn muốn làn người dùng có thể thao tác hoàn toàn chứ không làm sẵn cố định một chức năng nào. (Trừ khi điều đó là bắt buộc)
ncnx cũng mới tìm hiểu về access nhưng xem ra hạn chế cũng không nhỏ nhỉ.
Đang mò cái vụ menu : suy nghĩ thế này
Tạo một table chứa dữ liệu các menu
tblMenu(ID, level, name, label, object, object_type, action, action_type, enable)
- level:
----1
------11
------12
----------121
----------122
-----2
... Nói chung thuật toán này cũng không khó
- name, label : thì chỉ là tên của nó thôi
- object, object_type : ví dụ fromA thì type là from
- action, action_type : ví dụ fromA có action là click và type là view (chẳn hạn nếu report thì cho print luôn)
- enable (true/false): nếu true thì user được cấp quyền sẽ thấy menu này (field này sẽ update theo bản phân quyền của user khi user login vào chương trình). True: cho hiện menu/ false: ngược lại
---------
Mấy cái object, type sẽ tự động tập hợp khi user tạo menu mới
---------
Đó như vậy người dùng cũng có thể tạo/xóa menu cho riêng mình hìhi
Khả thi không nhỉ
Nếu bạn có demo hay, hoan nghênh bạn chia xẻ! -
RE: Thiết kế Ctrình phân quyền
no1blue > 08-12-10, 12:01 AM
trong bài này
em làm xong hết cái form login ấy
thì cho dù em nhập kỉu j thì kỉu
nó cũng báo Login Fail, check your Username and your password
mà dòng nào nghĩa là sao em ko hỉu ???
Trong đó : username là khóa ngoại liên kết với tblDSUser -
RE: Thiết kế Ctrình phân quyền
haquocquan > 13-12-10, 11:52 PM
(08-12-10, 12:01 AM)no1blue Đã viết: trong bài này
em làm xong hết cái form login ấy
thì cho dù em nhập kỉu j thì kỉu
nó cũng báo Login Fail, check your Username and your password
mà dòng nào nghĩa là sao em ko hỉu ???
Trong đó : username là khóa ngoại liên kết với tblDSUser
Bạn đưa bài của bạn lên đi, mọi người hỗ trợ
-
RE: Thiết kế Ctrình phân quyền
no1blue > 14-12-10, 12:25 AM
CHO EM HỎI XÍU
EM MUỐN LÀ KHI MÌNH PHÂN QUYỀN XONG RỒI ẤY
MUỐI KO CHO GUEST XEM CÁC FUNCTION CỦA ADMIN THÌ PHẢI CHỈNH CODE NHƯ THẾ NÀO ??
-
RE: Thiết kế Ctrình phân quyền
Noname > 14-12-10, 12:31 AM
Thì kiểm tra user đó có phải admin không, nếu không phải thì hiện câu thông báo không có quyền truy cập! Thế thôi!
If...then
Lệnh thế này
else
Lệnh thế nọ
End if