• kbmMW User authentication


    任何信息系统的一个非常重要的部分是能够对用户进行身份验证。 kbmMW在这里提供了非常强大的机制。 TkbmMWSimpleClient提供简单的用户身份验证机制,您可以在连接到应用程序服务器时传递UserName和Password。 但是,要创建最灵活和最强大的身份验证机制,有必要编写一些代码......这里的标准方法是使用令牌(tokens)来验证客户端请求,这样用户名和密码就不会在所有客户端请求上传递,这种方式是更安全的。

    服务器生成令牌而不是客户端。 客户只是接收回传的内容。 您可以使用clientident.customdata来存储用户的id,但是您也可以使用它来返回在“perm”中定义的内容。 我认为这种方法更好,所以看下面的代码:

    unit Unit11;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
      Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB,
      kbmMWServer, kbmMemTable, kbmMWSecurity, kbmMWExceptions,kbmMWuniDAC,
      DBAccess, Uni, kbmMWCustomConnectionPool;
    
    type
      TForm11 = class(TForm)
        mwServer: TkbmMWServer;
        Memo1: TMemo;
        tbmusers: TkbmMemTable;
        mwcpool: TkbmMWUNIDACConnectionPool;
        UniConnection1: TUniConnection;
        procedure mwServerAuthenticate(Sender: TObject;
          ClientIdent: TkbmMWClientIdentity; var Perm: TkbmMWAccessPermissions;
          var AMessage: string);
      private
        function IsUserLegit(UserName,password:string;var customdata,token:string):Boolean;
        function IsTokenLegit(token:string):Boolean;
      public
        { Public declarations }
      end;
    
    var
      Form11: TForm11;
    
    implementation
    
    {$R *.dfm}
    
    function TForm11.IsTokenLegit(token: string): Boolean;
    begin
      tbmusers.Lock;
      try
         if tbmusers.Locate('token',token,[]) then
         begin
           Result:=true;
           tbmusers.Edit;
           tbmusers.FieldByName('exppiry').AsDateTime:=Now+(15/(60*24));//当前时间+15分钟
           tbmusers.Post;
         end
         else
           Result:=false;
      finally
         tbmusers.Unlock;
      end;
    end;
    
    function TForm11.IsUserLegit(UserName, password: string; var customdata,
      token: string): Boolean;
    var
      conn:TkbmMWUNIDACConnection;
      qry:TUniQuery;
    begin
      Result := False;
      qry := TUniQuery.Create(nil);
      conn := TkbmMWUNIDACConnection(mwcpool.GetBestConnection(true, -1, nil, 180));
      try
        qry.Connection := conn.Database;
        qry.SQL.Add('select id from employees where name=:username and password=:password');
        qry.ParamByName('username').AsString := UserName;
        qry.ParamByName('password').AsString := password;
        qry.Open;
        if qry.Eof then
        begin
          Result := False;//用户名或密码错误
        end
        else
        begin
        //用户与密码正确,建立token并返回customdata.
          customdata := qry.Fields[0].AsString;
        //建立简单的token
          token := customdata + IntToStr(GetTickCount);
          Result := True;
        end;
      finally
        FreeAndNil(qry);
        FreeAndNil(conn);
      end;
    end;
    
    procedure TForm11.mwServerAuthenticate(Sender: TObject;
      ClientIdent: TkbmMWClientIdentity; var Perm: TkbmMWAccessPermissions;
      var AMessage: string);
    var
      userdata,
      token: string;
    begin  // no access by default
      perm:=[];
      //check to see if user already logged in
      if clientident.token='' then
      begin
         memo1.lines.add(clientident.password);
         if IsUserLegit(clientident.username,clientident.password,userdata,token) then
         begin
           clientident.Data:=userdata;
           clientident.Token:=token;
           perm:=[mwapRead, mwapWrite, mwapDelete, mwapExecute];
           try
              tbmusers.Lock;
              tbmusers.Insert;
              tbmusers.FieldByName('id').AsString:=userdata;
              tbmusers.FieldByName('token').AsString:=token;
              tbmusers.FieldByName('expiry').AsDateTime:=now+(15/(60*24));
              tbmusers.Post;
           finally
              tbmusers.Unlock;
           end;
         end
         else
            raise EkbmMWAuthException.Create(1,'Username or Password Invalid');
      end
      else
      begin
         if IsTokenLegit(clientident.token) then
            perm:=[mwapRead, mwapWrite, mwapDelete, mwapExecute]
         else
            raise EkbmMWAuthException.Create(2,'Timeout');
      end;
      clientident.Username:='';
      clientident.Password:='';
    end;
    
    end.
  • 相关阅读:
    Web前端开发中的各种CSS规范
    SVN简明课程
    使用django-compressor压缩静态文件
    今日头条视频Url嗅探
    python 异常类型
    抓包分析工具备注
    电子签章盖章之jQuery插件jquery.zsign
    程序员读书雷达
    在csdn里markdown感受
    如何在无趣的世界里,做一个有趣的人?
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/9464172.html
Copyright © 2020-2023  润新知