HanDs
管理员

[Delphi文章] 对已经存在的TCP系统进行登录验证 



由于登录帐号保存在数据库,要实现自己的验证机制,需要在WMS前面加上Socket代理,检查URL中包含

的SessionKey,验证流程:WMP -> Proxy -> WMS

主要是实现一个代理,利用Delphi本身带的控件IdMappedPortTCP很容易就实现了。


unit frmMains;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPServer, IdMappedPortTCP,
  StdCtrls;

type
  TfrmMain = class(TForm)
    Server: TIdMappedPortTCP;
    Label1: TLabel;
    lblConnections: TLabel;
    Memo1: TMemo;
    Button1: TButton;
    procedure ServerConnect(AThread: TIdMappedPortThread);
    procedure ServerDisconnect(AThread: TIdMappedPortThread);
    procedure ServerExecute(AThread: TIdMappedPortThread);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    procedure printf(const S: string);

  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

var
    ClientCount: Integer = 0;

type
  TThreadData = class
  public
    IsFirstRecv: Boolean;
  end;

procedure TfrmMain.ServerConnect(AThread: TIdMappedPortThread);
begin
    InterlockedIncrement(ClientCount);
    lblConnections.Caption:= IntTostr(ClientCount);

    AThread.Data:= TThreadData.Create;
    TThreadData(AThread.Data).IsFirstRecv:= True;
end;

procedure TfrmMain.ServerDisconnect(AThread: TIdMappedPortThread);
begin
    InterlockedDecrement(ClientCount);
    lblConnections.Caption:= IntTostr(ClientCount);

    // Auto free by TIdMappedPortThread
    //AThread.Data.Free;
end;

procedure TfrmMain.ServerExecute(AThread: TIdMappedPortThread);
var
    Header: string;
    n: Integer;
    Data: string;
    threadData: TThreadData;

    procedure CloseConnect;
    begin
        AThread.OutboundClient.Disconnect;
        AThread.Connection.Disconnect;
    end;
begin
    threadData:= TThreadData(AThread.Data);

    // first recv data, check is HTTP Protocol
    if (threadData <> nil) and threadData.IsFirstRecv then
    begin
        Data:= AThread.NetData;
        n:= Pos(#13, Data);
        if n  > 0 then
        begin
            Header:= Copy(Data, 1, n - 1);
            printf(Header);

            // sample: check URL if has SID string
            // GET /?SID=XXXXXXX HTTP/1.1
            if Copy(Header, 1, 5) = 'GET /' then
            begin
                // check SessionID of Login
                // todo: really check login
                if Pos('SID=', Header) = 0 then
                begin
                    printf('Access denied. ************');
                    CloseConnect;
                end;
            end
            else CloseConnect;
        end
        else CloseConnect;

        threadData.IsFirstRecv:= False;
    end;
end;

procedure TfrmMain.Button1Click(Sender: TObject);
begin
     Memo1.Clear;
end;

procedure TfrmMain.printf(const S: string);
begin
    Memo1.Lines.Add(S);
end;

end.

 


学习中请遵守法律法规,本网站内容均来自于互联网,本网站不负担法律责任
#1楼
发帖时间:2016-7-9   |   查看数:0   |   回复数:0
游客组
快速回复