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:
Public username as string
OK, bây giờ bạn đã đủ đồ nghề để tạo form đăng nhập.
Xem hình
Đầ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:
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:
Bây giờ tới nút cmdGuest
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
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
sai ở table tblWorkGroup, vì như vậy thì ở mỗi level ta chỉ tạo được một user thôi
Mình xin đính chính lại table này
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
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
OK, bây giờ đồ nghề đầy đủ, các bạn vẽ mainform rồi chứ/? Đặt tên cái form đó là frmMain.
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
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.
Và nút guest cũng tương tự
Hihi, đáng lẽ có thể sửa quyền khách cho hợp lý hơn, nhưng mình copy paster cho nhanh
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
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:
Public username as string
OK, bây giờ bạn đã đủ đồ nghề để tạo form đăng nhập.
Xem hình
Đầ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:
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:
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:
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:
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
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:
Function checkuser() As IntegerOn 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
OK, bây giờ đồ nghề đầy đủ, các bạn vẽ mainform rồi chứ/? Đặt tên cái form đó là frmMain.
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:
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:
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:
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
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>
Trả lờiXóaPass 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/thuvienthuthuat/home/LOGIN.rar?attredirects=0&d=1
Bạn có cách nào khóa table không cho Guest sửa được không. Chỉ cần đăng nhập được vào bên trong tôi không cần mật khẩu cũng có thể dùng phân quyền Admin. (nhấn nút Custom Quick Access toolbả của office 2007, chọn More commands... Sau đó tìm đến Current Database > đánh dấu Display Navigation Pane khởi động lại là có thể sửa được các table, trong đó có table chứa mật khẩu của bạn.)
Trả lờiXóaMình không dùng Access 2007 nên không rành lắm. Nhưng thường thì chương trình của mình chỉ có cái xác. Còn các table để ở 1 nơi khác. Chỉ link khi sử dụng và xóa khi khởi động/ thoát. Nên dù bạn có vào database cũng chẳng xem được gì! Bạn nên tham khảo thêm các bài viết về auto link/ delete table!
Trả lờiXóaXin chào!
Trả lờiXóaMình vừa cài và test với Office 2007.
Đúng như comment trên đã nói, Access 2007 không hỗ trợ việc dấu các table. Vì thế. Mình xin gợi ý 1 hướng khác là ta để table trong 1 file khác. Mỗi khi kiểm tra Password, ta kết nối với file đó thông qua VBA. ( xem các bài về kết nối/ thao tác với table ngoài).
Sau đó, ta khóa VBA xem như an toàn thêm được 1 ít. Ai có ý kiến gì hay xin đóng góp!
Không xem được module huhu. Bi khoá rồi..mình làm theo hướng dẫnn nhưng chạy không được. thấy có chương trình việt sẵn mừng thâm nhưng thất vọng quá
Trả lờiXóaThank web này nhé
Trả lờiXóaCó nhiều tài liệu bổ ích
Trần Trung
http://trantrungnd1.violet.vn
Bạn ơi! nó báo lỗi ở chổ ".value" ở dòng 2 thì làm sao? Xin bạn chỉ giúp.thanks
Trả lờiXóaPrivate 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
Y!H:congtu_chiuchoi_bmt
bạn có làm đúng hướng dẫn chưa! có 2 ô: txtPassWord và txtPassTemp chưa?
Trả lờiXóaHi. Mọi người
Trả lờiXóaEm là thành viên mới của forum em cũng vừa học acces thôi nên vẫn còn yếu lắm.
Em có vấn đề này mong mọi người giúp đỡ
Em có một bảng TaiKhoanVaQuyen
(taikhoan:text, matkhau:text, quyenxem:boolean, quyencapnhat:boolean, quyenquantri:boolean)
Bi giờ em muốn tạo một form đăng nhập mà sau khi đăng nhập tương ứng với mỗi quyền sẽ mở một form riêng
Mong mọi người giúp đỡ. Nếu có demo các tốt vì em vẫn chưa biết nhiều lệnh VB lắm
ThankS
Email: khaihb@gmail.com
ah noname oi eh cho em xin pass trong visual dc khong em muon xen code ..em dag rat can ah jup em nhe cam on ah nhiu nhiu.......gmail cua em la :ten3yb@gmail.com
Trả lờiXóacai bai phan quyen tren do
Trả lờiXóaHi Noname.
Trả lờiXóaBạn có thể giải thích cho mình chỗ tạo biến toàn cục "Public username as string" không?
Có phải là mình tạo trong một cái module riêng lẻ không? Rồi khi tạo xong mình gọi nó như thế nào để có thể xét trên tất cả các form?
Bạn có thể cho mình pass để coi module phanquyen của bạn không? Mình chỉ còn vướng chỗ checkuser nữa. Mail của mình là sara_yumi2000@yahoo.com
Hi vọng bạn sớm trả lời. Thx Noname nhiều.
Phần mềm MSchool(Quản lý điểm và xét tốt nghiệp THCS theo TT58 - thông tư áp dụng học kỳ 2 năm học 2011-2012
Trả lờiXóaPhần mềm MSchool(Quản lý điểm và xét hoàn thành chương trình tiểu học theo TT32 - thông tư áp dụng năm học 2010-2011
http://www.mediafire.com/myfiles.php
Thân chào: mình tên Trang ,
Trả lờiXóamình làm đúng như bạn chỉ dẫn , nhưng không work, có lẽ sai đâu đó,
1. chỗ txtPassTemp, không lấy được pass,
2. khi click vào Login , hay guess , không mở bảng FrmMain
Bạn có thể hướng dẫn kỹ hơn không . Thanks
Sorry email của mình là : ttttrang2001@gmail.com
Trả lờiXóahay, thank ban!
Trả lờiXóabut mình nghĩ để đơn giản hóa, thì ban k cần text box đặt tên là txtPassTemp để nhận giá trị trả về. chỉ cần ở nut login bạn sử dụng hàm Dlookup sau if (nếu pass = pass of use - lấy ra bằng dlookup - thi ...
Hay đấy!
Trả lờiXóa