利用数据库实现应用程序的多用户登录
几乎所有的财务类软件、管理类软件,在操作者进入系统之前都要进行用户身份的验证,以确保系统的安全,只有合法用户才能进入系统,而且不同的用户具有不同的权限。笔者在编写某工程管理软件的时,遇到同样的问题:由于工程管理的内容庞大,不同的项目由不同的操作者在不同的终端进行操作,某些机密性的内容只能由具有特定身份的用户访问、操作,因此,要求所编制的程序具有多用户登录功能,不同的用户具有不同的权限,所有的用户都处于系统管理员的管理之下,系统管理员具有最高的操作权限,可以进行添加或删除用户、更改口令等操作。经过多种方法的比较,笔者用Delphi5.0以数据库的方式实现了这一功能。
程序要求:
系统具双重验证功能,非授权用户不能进入系统,授权用户口令不正确者也无法进入系统;
三次输入用户名或口令不正确时自动退出系统;
不同的用户具有不同的操作权限;
为方便操作,输入用户名后按回车键转入口令输入框,输入口令后按回车键即为“确定”。
具体操作过程如下。
1.打开Database Desktop,新建一用户数据表,数据表类型选择Paradox 7.0,结构如表1所求。
表1
字段名称 字段类型 字段长度 说明
UserName A 10 作主索引
PassWord A 20
建成数据表后,选择“Table Properties”列表框中的“password Security”项,为数据表本身添加保护密码“mydemo”(密码可自定义,注意大小写),添加密码后的数据表更加安全,无法利用数据表工具查看其内容,达到存储用户名和口令的目的。
为了使数据表能输入汉字,选择“Table Properties”列表框中的“Table Language”一项,将数据表语言设为“Paradox China 936”。
最后,将数据表另存为(Save as…)Demo.db。
2.启动Delphi,新建一工程,所需对象及其属性值如表2所示:
表2
对象 属性 值
Form1 Name LoginForm
Caption 欢迎使用工程管理信息系统
BorderIcons [biSystemMenu,biMinimize]
Label1 Caption Kingstore Studio
Label2 Caption 工程管理信息系统V1.0
Label3 Caption 请输入正确的用户名及密码,以便登录到工程管理信息系统
Label4 Caption 用户名(&U)
Label5 Caption 口 令(&P)
Image1 Picture (载入一幅图)
Edit1 Name EditUser
Text (空)
Edit2 Name EditPsw
Text (空)
PasswordChar *
Button1 Name OKBtn
Caption 确定(&O)
Button2 Name CanBtn
Caption 取消(&C)
Table1 Name Table_User
TableName Demo.db
Active True
IndexFieldNames UserName
DataSource1 Name DataSource_User
DataSet Table_User
所有对象的摆放位置如图1所示。
图1
3.编写代码 (1)双击OKBtn按钮,在OKBtn按钮的OnClick事件中添加如下代码: procedure TLoginForm.OKBtnClick(Sender: TObject); begin TimeID:=TimeID+1; //每单击一次“确定”,计时器加一 if TimeID<=3 then //用户名或口令错误输入超过三次,系统关闭 begin Table_User.SetKey; Table_User.Fields[0].AsString:=EditUser.Text; Table_User.GotoKey; //检索用户数据表 if (EditUser.Text = Table_User.Fields[0].AsString) and (EditPsw.Text = Table_User.Fields[1].AsString) then ModalResult:=mrOK //用户名和口令都正确时程序正常进入的标志 else begin if EditUser.Text <> Table_User.Fields[0].AsString then //用户名不对 begin Application.MessageBox('非法用户,请您输入正确的用户名!','用户名',MB_OK+MB_ICONEXCLAMATION); EditUser.SetFocus; //用户名不对时自动将光标置于用户名输入框 end else //如果口令不正确 Application.MessageBox('输入密码错误,请再输入一次','密码',MB_OK+MB_ICONEXCLAMATION); EditPsw.SetFocus; //口令不正确时自动将光标置于口令输入框 end end else begin Application.Terminate; //三次错误输入用户名或口令时退出系统 end end; 为了能使程序正常编译运行,必须在implementation之前加入计时器变量声明: Var TimeID : Integer; (2)双击CanBtn按钮,在CanBtn按钮的Onclick事件中添加结束程序代码: procedure TLoginForm.CanBtnClick(Sender: TObject); begin Application.Terminate; end; (3)选中EditUser编辑框,在对象监视器(Object Inspector)的事件(Events)页中双击OnKeyDown一项,在EditUser的OnKeyDown事件中添加如下代码: procedure TLoginForm.EditUserKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key=$0D then if EditPsw.CanFocus then EditPsw.SetFocus; //如果按下回车键,则转入口令输入框 end; (4)同样选中EditPsw编辑框,在对象监视器(Object Inspector)的事件(Events)页中双击OnKeyDown一项,在EditPsw的OnKeyDown事件中添加如下代码: procedure TLoginForm.EditPswKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key=$0D then LoginForm.OKBtnClick(Sender); //如果按下回车键,则相当于单击“确定”按钮 end; (5)由于用户数据表本身已经加密,每次执行程序利用数据表之前,都会弹出输入用户数据表密码的对话框,影响了程序的完整性,为了解决这一问题,须在使用用户数据之前让系统自动为其添加密码,以免弹出此对话框。可用Ttable的Session事件来完成这一任务。 选中Table_User数据表对象,在对象监视器(Object Inspector)的事件(Events)页中双击BeforeOpen一项,在Table_User的BeforeOpen事件中添加如下代码: procedure TLoginForm.Table_UserBeforeOpen(DataSet: TDataSet); begin Session.AddPassword('mydemo'); //“mydemo”即为用户数据表的密码 end; 完成上述工作后按F9键执行程序,即可出现如图2所示的多用户登录对话框。图2
在本例中,笔者采用ModalResult:=mrOK作为用户名和口令全部正确时程序正常启动的标志,在实际应用中,可以将此登录窗体(LoginForm)作为被利用的窗体(Available forms),在主窗体(Main form)启动之前用ModalResult作为正常登录的验证,如果ModalResult为mrOK,则说明用户正常登录,否则程序中止。当用户正常登录后,可以根据登录用户名的不同在主程序中对不同的用户的功能加以区分,比如可以设定用户名为“Administrator”的用户为具有最高操作权限的用户,其他用户根据不同情况使主程序相应的某些功能失效,以限制此类用户的使用。也可以事先在用户数据表中直接建立诸如“使用级别”的字段,不同的用户有不同的使用级别,在主程序中根据使用级别限制功能,笔者在实际编程已应用了这一方法,限于篇幅,此处不再举例,对此感兴趣的读者不妨自己动手试试。 在正式使用的程序中,如果用户数据表被他人的数据表所替代,别人则可以非常轻松地进入系统。对于这一点,需要说明的是由于被替代的用户数据表的文件名、密码、不同的字段及其名称、被索引的字段等很难与系统使用的完全相同,所以即使被替换了,系统也无法正常运行。 上述程序分别用Delphi4.0、Delphi5.0在Windows98、Windows2000中运行通过