【问题标题】:database usernames and passwords in delphidelphi中的数据库用户名和密码
【发布时间】:2015-02-10 16:23:56
【问题描述】:

使用 Delphi XE2。

我有一个数据库,其中有一个名为 users 的表。它有一个 user_id 字段、一个用户名字段、一个密码字段和一个 Active 字段。 (user_id 是标识每个用户的唯一编号...1、2、3 等)。

我正在编写一个需要用户名和密码才能登录的数据库软件包。 (我已经创建了一个登录表单)。

如何让它匹配/检查数据库中的用户名和密码,然后允许用户继续进入软件?另外,如果用户已登录,我希望活动字段存储在数据库中“Y”,如果用户未登录,我希望将“N”存储在数据库中。这可行吗?

我通过 TADQuery 和 TDataSource 连接到 users 表。

我认为可以帮助我入门的功能示例(在单击登录表单上的登录按钮时调用它)。

function TfrmLogin.CheckUser: Boolean;
begin
while not dmData.qryUser.Eof do
begin
if(editName.Text <> qryUser.FieldByName('uname').AsString) or (editPassword.Text <> qryUser.FieldByName('pword').AsString)
  then ShowMessage('Username and/or Password not recognised');
    Exit;
End;

【问题讨论】:

  • 为什么要将登录状态存储在数据库中?
  • 老实说,只是看看能不能做到。如果您建议不要存储它,那么我会接受您的意见。我已经很久没有这样做了。
  • 您在任务的哪一部分遇到了问题?到目前为止,您尝试过什么,您在哪里卡住了?
  • 允许用户使用存储在数据库中的用户凭据登录软件......这就是我的目标。我尝试了以下方法,如果 name.text / password.text = fieldbyname('name').asstring / fieldbyname('password').asstring 然后开始 LoginForm.Hide; mainform.create(self);尝试 Mainform.showmodal finally mainform.free else ShowMessage('uname or pword not recognize'), Close;对不起,垃圾示例,真的不知道该怎么说。
  • 请,请,请不要在您的数据库中以纯文本形式存储密码。至少,存储一个散列版本并比较散列。对可以保护您和您的用户的一些基本事项进行一些研究。

标签: database delphi delphi-xe2 sybase-asa


【解决方案1】:

遍历数据库中的所有行是不够的,尤其是当您获得的用户数量超过少数时。您需要从数据库中为特定用户输入SELECT,然后查看是否返回结果。您可以仅根据用户名执行SELECT

qryUser.SQL.Text := 'SELECT uname, pword FROM users WHERE uName = :uname';
qryUser.ParamByName('uname').AsString := editName.Text;
try
  qryUser.Open;
  if qryUser.IsEmpty then // No record found for user
    // Handle error
  else
  begin
    if qryUser.FieldByName('pword').AsString <> editPassword.Text then
      // Handle password mismatch;
  end;
finally
  qryUser.Close;
end;

从您的问题中不清楚您正在使用哪些数据库组件(TADQuery 可能是TADOQuery 的拼写错误,或者可能是其他东西)。如果实际上是TADOQuery,您需要对代码进行一些小的更改。 (其实只有三处小改动,两处参数赋值,一处读取密码值。)

qryUser.SQL.Text := 'SELECT uname, pword FROM users WHERE uName = :uname';
qryUser.Params.ParamByName('uname').Value := editName.Text;
try
  qryUser.Open;
  if qryUser.IsEmpty then // No record found for user
    // Handle error
  else
  begin
    if qryUser.FieldByName('pword').Value <> editPassword.Text then
      // Handle password mismatch;
  end;
finally
  qryUser.Close;
end;

【讨论】:

    【解决方案2】:

    我和 Sam 在一起,如果可能的话,不要在数据库中存储密码。如果数据库支持 Active Directory 身份验证(MS/SQL、Oracle、DB2、MySQL、SyBase),请在尝试连接到数据库之前使用用户名和密码针对 Active Directory 进行验证。然后只将用户名和活动标志存储在用户表中。

    在您尝试连接到数据库之前,此功能会询问 Active Directory 用户和密码是否有效。然后,您可以构建与数据库的连接参数(我假设您正在使用 FireDAC 和 TADConnection see here 以获取说明)。尝试打开连接,如果失败,则用户根本无法访问数据库。如果通过,则像 Ken 建议的那样查询用户表,但测试活动字段而不是密码。这样,没有人可以看到用户密码,并且您不必在应用程序中管理密码。通过使用这种方法,即使您在数据库上使用 Active Directory 身份验证,仍然需要知道用户的 Active Directory 密码才能访问您的应用程序。

    function TfrmPassword.ActiveDirectoryValidate: Boolean;
    var
      LHandle: THandle;
      lDomainName: String;
    begin
      Screen.Cursor := crHourglass;
      try
       // Get the Domain Name
       lDomainName := GetEnvironmentVariable('USERDOMAIN');
       // Test the user Logon
       Result := LogonUser(PWideChar(edtUserID.Text),
                           PWideChar(lDomainName),
                           PWideChar(edtPassword.Text),
                           LOGON32_LOGON_NETWORK,
                           LOGON32_PROVIDER_DEFAULT,
                           LHandle);
       // If True, we got a Handle, so close it
       if Result then
        CloseHandle(LHandle);
    
      finally
       Screen.Cursor := crDefault;
      end;
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-13
      • 2016-02-05
      • 2012-05-08
      • 2016-12-04
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 1970-01-01
      相关资源
      最近更新 更多