delphi 使用oauth的控件

2021-02-15 03:16

阅读:616

标签:byte   begin   inpu   form   blog   sha   code   hex   pat   

    unit OAuth;
    interface
    uses
      Classes, SysUtils, IdURI, Windows;
    type
      EOAuthException = class(Exception);
      TOAuthConsumer = class;
      TOAuthToken = class;
      TOAuthRequest = class;
      TOAuthSignatureMethod = class;
      TOAuthSignatureMethod_HMAC_SHA1 = class;
      TOAuthSignatureMethod_PLAINTEXT = class;
      TOAuthConsumer = class
      private
        FKey: string;
        FSecret: string;
        FCallback_URL: string;
        procedure SetKey(const Value: string);
        procedure SetSecret(const Value: string);
        procedure SetCallback_URL(const Value: string);
      public
        constructor Create(Key, Secret: string); overload;
        constructor Create(Key, Secret: string; Callback_URL: string); overload;
        property Key: string read FKey write SetKey;
        property Secret: string read FSecret write SetSecret;
        property Callback_URL: string read Fcallback_URL write SetCallback_URL;
      end;
      TOAuthToken = class
      private
        FKey: string;
        FSecret: string;
        procedure SetKey(const Value: string);
        procedure SetSecret(const Value: string);
      public
        constructor Create(Key, Secret: string);
        function AsString: string; virtual;
        property Key: string read FKey write SetKey;
        property Secret: string read FSecret write SetSecret;
      end;
      TOAuthRequest = class
      private
        FParameters: TStringList;
        FHTTPURL: string;
        FScheme: string;
        FHost: string;
        FPath: string;
        FFields: string;
        FVersion: string;
        FBaseString: string;
        FGetString: string;
        procedure SetHTTPURL(const Value: string);
        procedure SetBaseString(const Value: string);
        procedure SetVersion(const Value: string);
        function GenerateNonce: string;
        function GenerateTimeStamp: string;
        function GetSignableParameters: string;
      public
        constructor Create(HTTPURL: string);
        function FromConsumerAndToken(Consumer: TOAuthConsumer; Token: TOAuthToken;
                                      HTTPURL: string): TOAuthRequest;
        procedure Sign_Request(Signature_Method: TOAuthSignatureMethod; Consumer: TOAuthConsumer;
                              Token: TOAuthToken);
        function Build_Signature(Signature_Method: TOAuthSignatureMethod; Consumer: TOAuthConsumer;
                              Token: TOAuthToken): string;
        property BaseString: string read FBaseString write SetBaseString;
        property Version: string read FVersion write SetVersion;
        property Parameters: TStringList read FParameters;
        property HTTPURL: string read FHTTPURL write SetHTTPURL;
        property Scheme: string read FScheme;
        property Host: string read FHost;
        property Path: string read FPath;
        property Fields: string read FFields;
        property GetString: string read FGetString;
      end;
      TOAuthSignatureMethod = class
      public
        function check_signature(Request: TOAuthRequest; Consumer: TOAuthConsumer;
                                 Token: TOAuthToken; Signature: string): boolean;
        function get_name(): string; virtual; abstract;
        function build_signature(Request: TOAuthRequest; Consumer: TOAuthConsumer;
                                 Token: TOAuthToken): string; virtual; abstract;
      end;
      TOAuthSignatureMethod_HMAC_SHA1 = class(TOAuthSignatureMethod)
      public
        function get_name(): string; override;
        function build_signature(Request: TOAuthRequest; Consumer: TOAuthConsumer;
                                 Token: TOAuthToken): string; override;
      end;
      TOAuthSignatureMethod_PLAINTEXT = class(TOAuthSignatureMethod)
      public
        function get_name(): string; override;
        function build_signature(Request: TOAuthRequest; Consumer: TOAuthConsumer;
                                 Token: TOAuthToken): string; override;
      end;
      TOAuthUtil = class
      public
        class function urlEncodeRFC3986(URL: string):string;
        class function urlDecodeRFC3986(URL: string):string;
      end;
    const
      UnixStartDate : TDateTime = 25569;
    implementation
    uses
      IdGlobal, IdHash, IdHashMessageDigest, IdHMACSHA1, IdCoderMIME;
    function DateTimeToUnix(ConvDate: TDateTime): Longint;
    var
      x: double;
      lTimeZone: TTimeZoneInformation;
    begin
      GetTimeZoneInformation(lTimeZone);
      ConvDate := ConvDate + (lTimeZone.Bias / 1440);
      x := (ConvDate - UnixStartDate) * 86400;
      Result := Trunc(x);
    end;
    function _IntToHex(Value: Integer; Digits: Integer): String;
    begin
        Result := SysUtils.IntToHex(Value, Digits);
    end;
    function XDigit(Ch : Char) : Integer;
    begin
        if (Ch >= 0) and (Ch ‘9) then
            Result := Ord(Ch) - Ord(0)
        else
            Result := (Ord(Ch) and 15) + 9;
    end;
    function IsXDigit(Ch : Char) : Boolean;
    begin
        Result := ((Ch >= 0) and (Ch ‘9)) or
                  ((Ch >= a) and (Ch ‘f)) or
                  ((Ch >= A) and (Ch ‘F));
    end;
    function htoin(Value : PChar; Len : Integer) : Integer;
    var
        I : Integer;
    begin
        Result := 0;
        I      := 0;
        while (I and (Value[I] =  ) do
            I := I + 1;
        while (I and (IsXDigit(Value[I])) do begin
            Result := Result * 16 + XDigit(Value[I]);
            I := I + 1;
        end;
    end;
    function htoi2(Value : PChar) : Integer;
    begin
        Result := htoin(Value, 2);
    end;
    function UrlEncode(const S : String) : String;
    var
        I : Integer;
        Ch : Char;
    begin
        Result := ‘‘;
        for I := 1 to Length(S) do begin
            Ch := S[I];
            if ((Ch >= 0) and (Ch ‘9)) or
               ((Ch >= a) and (Ch ‘z)) or
               ((Ch >= A) and (Ch ‘Z)) or
               (Ch = .) or (Ch = -) or (Ch = _) or (Ch = ~)then
                Result := Result + Ch
            else
                Result := Result + % + _IntToHex(Ord(Ch), 2);
        end;
    end;
    function UrlDecode(const Url : String) : String;
    var
        I, J, K, L : Integer;
    begin
        Result := Url;
        L      := Length(Result);
        I      := 1;
        K      := 1;
        while TRUE do begin
            J := I;
            while (J and (Result[J]  %) do begin
                if J  K then
                    Result[K] := Result[J];
                Inc(J);
                Inc(K);
            end;
            if J > Length(Result) then
                break;                   { End of string }
            if J > (Length(Result) - 2) then begin
                while J do begin
                    Result[K] := Result[J];
                    Inc(J);
                    Inc(K);
                end;
                break;
            end;
            Result[K] := Char(htoi2(@Result[J + 1]));
            Inc(K);
            I := J + 3;
            Dec(L, 2);
        end;
        SetLength(Result, L);
    end;
    { TOAuthConsumer }
    constructor TOAuthConsumer.Create(Key, Secret: string);
    begin
      FKey := Key;
      FSecret := Secret;
      FCallBack_URL  := ‘‘;
    end;
    constructor TOAuthConsumer.Create(Key, Secret, Callback_URL: string);
    begin
      FKey := Key;
      FSecret := Secret;
      FCallBack_URL  := Callback_URL;
    end;
    procedure TOAuthConsumer.SetCallback_URL(const Value: string);
    begin
      FCallback_URL := Value;
    end;
    procedure TOAuthConsumer.SetKey(const Value: string);
    begin
      FKey := Value;
    end;
    procedure TOAuthConsumer.SetSecret(const Value: string);
    begin
      FSecret := Value;
    end;
    { TOAuthToken }
    function TOAuthToken.AsString: string;
    begin
      result := oauth_token= + Self.Key + &oauth_token_secret= + Self.Secret;
    end;
    constructor TOAuthToken.Create(Key, Secret: string);
    begin
      FKey := Key;
      FSecret := Secret;
    end;
    procedure TOAuthToken.SetKey(const Value: string);
    begin
      FKey := Value;
    end;
    procedure TOAuthToken.SetSecret(const Value: string);
    begin
      FSecret := Value;
    end;
    { TOAuthRequest }
    function TOAuthRequest.Build_Signature(Signature_Method: TOAuthSignatureMethod;
      Consumer: TOAuthConsumer; Token: TOAuthToken): string;
    begin
      Result := Signature_Method.build_signature(Self, Consumer, Token);
    end;
    constructor TOAuthRequest.Create(HTTPURL: string);
    var
      x,y: integer;
    begin
      FHTTPURL := HTTPURL;
      FScheme := Copy(FHTTPURL, 0, 7);
      x := AnsiPos(.com, FHTTPURL);
      y := AnsiPos(?, FHTTPURL);
      FHost := Copy(FHTTPURL, 8, x-4);
      FPath := Copy(FHTTPURL, x + 4, Length(HTTPURL) - y - 1);
      if y > 0 then
        FFields := Copy(FHTTPURL, y + 1, Length(HTTPURL));
      FVersion := 1.0;
      FParameters := TStringList.Create;
    end;
    function TOAuthRequest.FromConsumerAndToken(Consumer: TOAuthConsumer;
      Token: TOAuthToken; HTTPURL: string): TOAuthRequest;
    begin
      Self.FParameters.Clear;
      Self.FParameters.Add(oauth_consumer_key= + Consumer.Key);
      Self.FParameters.Add(oauth_nonce= + Self.GenerateNonce);
      Self.FParameters.Add(oauth_timestamp= + Self.GenerateTimeStamp);
      if Token  nil then
        FParameters.Add(oauth_token= + Token.Key);
      Self.FParameters.Add(oauth_version= + Self.Version);
      Result := Self;
    end;
    function TOAuthRequest.GenerateNonce: string;
    var
      md5: TIdHashMessageDigest;
    begin
      md5 := TIdHashMessageDigest5.Create;
      Result := md5.HashStringAsHex(GenerateTimeStamp);
      md5.Free;
    end;
    function TOAuthRequest.GenerateTimeStamp: string;
    begin
      Result := IntToStr(DateTimeToUnix(Now));
    end;
    function TOAuthRequest.GetSignableParameters: string;
    var
      x: integer;
      parm: string;
    begin
      parm := ‘‘;
      x := FParameters.IndexOfName(oauth_signature);
      if x  -1 then
        FParameters.Delete(x);
      for x := 0 to FParameters.Count - 1 do
      begin
        if x = 0 then
        begin
          FParameters.ValueFromIndex[x] := TOAuthUtil.urlEncodeRFC3986(FParameters.ValueFromIndex[x]);
          parm := FParameters.Names[x] + TOAuthUtil.urlEncodeRFC3986(=) + TIdURI.PathEncode(FParameters.ValueFromIndex[x]);
        end
        else
          parm := parm + TOAuthUtil.urlEncodeRFC3986(&) +
                  FParameters.Names[x] + TOAuthUtil.urlEncodeRFC3986(= + FParameters.ValueFromIndex[x])
      end;
      Result := parm;
    end;
    procedure TOAuthRequest.SetBaseString(const Value: string);
    begin
      FBaseString := Value;
    end;
    procedure TOAuthRequest.SetHTTPURL(const Value: string);
    var
      x,y: integer;
    begin
      FHTTPURL := Value;
      FScheme := Copy(FHTTPURL, 0, 7);
      x := AnsiPos(.com, FHTTPURL);
      y := AnsiPos(?, FHTTPURL);
      FHost := Copy(FHTTPURL, 8, x-4);
      if y > 0 then
        FPath := Copy(FHTTPURL, x + 4, y - (x + 4))
      else
        FPath := Copy(FHTTPURL, x + 4, Length(HTTPURL) - y - 1);
      if y > 0 then
        FFields := Copy(FHTTPURL, y + 1, Length(HTTPURL));
    end;
    procedure TOAuthRequest.SetVersion(const Value: string);
    begin
      FVersion := Value;
    end;
    procedure TOAuthRequest.Sign_Request(Signature_Method: TOAuthSignatureMethod;
      Consumer: TOAuthConsumer; Token: TOAuthToken);
    var
      signature: string;
      x: integer;
    begin
      FParameters.Insert(2 ,oauth_signature_method= + Signature_Method.get_name);
      //FParameters.Sort;
      signature := Self.Build_Signature(Signature_Method, Consumer, Token);
      signature := TOAuthUtil.urlEncodeRFC3986(signature);
      FParameters.Insert(3, oauth_signature= + signature);
      for x := 0 to FParameters.Count - 1 do
      begin
        if x = 0 then
          FGetString := FParameters.Names[X] + = + FParameters.ValueFromIndex[x]
        else
          FGetString := FGetString + & + FParameters.Names[X] + = + FParameters.ValueFromIndex[x];
      end;
    end;
    { TOAuthUtil }
    class function TOAuthUtil.urlDecodeRFC3986(URL: string): string;
    begin
      result := TIdURI.URLDecode(URL);
    end;
    class function TOAuthUtil.urlEncodeRFC3986(URL: string): string;
    var
      URL1: string;
    begin
      URL1 := URLEncode(URL);
      URL1 := StringReplace(URL1, +,  , [rfReplaceAll, rfIgnoreCase]);
      result := URL1;
    end;
    { TOAuthSignatureMethod }
    function TOAuthSignatureMethod.check_signature(Request:TOAuthRequest;
      Consumer: TOAuthConsumer; Token: TOAuthToken; Signature: string): boolean;
    var
      newsig: string;
    begin
       newsig:= Self.build_signature(Request, Consumer, Token);
      if (newsig = Signature) then
        Result := True
      else
        Result := False;
    end;
    { TOAuthSignatureMethod_HMAC_SHA1 }
    function TOAuthSignatureMethod_HMAC_SHA1.build_signature(Request: TOAuthRequest;
      Consumer: TOAuthConsumer; Token: TOAuthToken): string;
      function Base64Encode(const Input: TIdBytes): string;
      begin
        Result := TIdEncoderMIME.EncodeBytes(Input);
      end;
      function EncryptHMACSha1(Input, AKey: string): TIdBytes;
      begin
        with TIdHMACSHA1.Create do
        try
          Key := ToBytes(AKey);
          Result := HashValue(ToBytes(Input));
        finally
          Free;
        end;
      end;
    var
      parm1, parm: string;
      consec, toksec: string;
    begin
      parm1 := Request.GetSignableParameters;
      parm := TOAuthUtil.urlEncodeRFC3986(Request.Scheme) +
              TOAuthUtil.urlEncodeRFC3986(Request.Host) +
              TOAuthUtil.urlEncodeRFC3986(Request.Path);
      if Request.Fields  ‘‘ then
      begin
        parm := parm + & + TOAuthUtil.urlEncodeRFC3986(Request.Fields);
        parm := parm +  TOAuthUtil.urlEncodeRFC3986(&) + parm1;
      end
      else
        parm :=  parm + & + parm1;
      Request.BaseString := GET& + parm;
      if Token  nil then
      begin
        consec := TOAuthUtil.urlEncodeRFC3986(Consumer.Secret);
        toksec := TOAuthUtil.urlEncodeRFC3986(Token.Secret);
        consec := consec + & + toksec;
        Result := Base64Encode(EncryptHMACSha1(Request.BaseString, consec))
      end
      else
      begin
        consec := TOAuthUtil.urlEncodeRFC3986(Consumer.Secret);
        consec := consec + &;
        Result := Base64Encode(EncryptHMACSha1(Request.BaseString, consec));
      end;
    end;
    function TOAuthSignatureMethod_HMAC_SHA1.get_name: string;
    begin
      result := HMAC-SHA1;
    end;
    { TOAuthSignatureMethod_PLAINTEXT }
    function TOAuthSignatureMethod_PLAINTEXT.build_signature(Request: TOAuthRequest;
      Consumer: TOAuthConsumer; Token: TOAuthToken): string;
    begin
      if Token  nil then
        Result := TOAuthUtil.urlEncodeRFC3986((Consumer.Secret + & + Token.Secret))
      else
        Result := TOAuthUtil.urlEncodeRFC3986((Consumer.Secret));
    end;
    function TOAuthSignatureMethod_PLAINTEXT.get_name: string;
    begin
      Result := PLAINTEXT;
    end;
    end.

 

delphi 使用oauth的控件

标签:byte   begin   inpu   form   blog   sha   code   hex   pat   

原文地址:https://www.cnblogs.com/westsoft/p/8439801.html


评论


亲,登录后才可以留言!