[Delphi] TIdHTTP 통해 https 통신

Indy Component 들 중 IdHTTP라는 Component 이용하여  웹 통신

 

IdHTTP는 http프로토콜 제공해주는 7가지 중 GET, POST방식 모두 사용해서 통신하여  구현하고자 하는 프로그램에 맞게 사용 가능합니다.

델파이 10.3.2 진행

 1. Get 방식 일경우(http, https)

  pURL --> https://도메인주소.com?name1=value1&name2=value2  

 pAuthorization --> Authorization : 인증키 

//{$region 'Https/ Get방식'}
//pURL : 웹주소( https://도메인주소.com?파라미터)   
//pAuthorization  : 인증키(Authorization)
function httpsGet(pURL,  pAuthorization : WideString) : WideString;
Var
  idhttps: TIdHTTP;
  sslIOHandler : TIdSSLIOHandlerSocketOpenSSL;
  lStream : TStringStream;  
begin
  Try
    Result := '';
    idhttps := TIdHTTP.Create();
    lStream := TStringStream.Create(nil);
    sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    Try
      sslIOHandler.SSLOptions.Method := sslvSSLv23;
      sslIOHandler.SSLOptions.Mode := sslmClient;

      idhttps.IOHandler := sslIOHandler;

      idhttps.Request.CustomHeaders.Add(pAuthorization);
      idhttps.HandleRedirects :=False;
      idhttps.Request.Method := 'GET';
      idhttps.Response.ContentType := 'application/json; charset=utf-8';
      idhttps.ConnectTimeout := 5000;
      idhttps.ReadTimeout := 5000;
      
      lStream.Position := 0;
      idhttps.Get(pURL, lStream, []);

    Finally
      Result :=  TEncoding.UTF8.GetString(lStream.Bytes,0, lStream.Size); 
      FreeAndNil(lStream);
      FreeAndNil(idhttps);
      FreeAndNil(sslIOHandler);
    End;
  except
    on E: EIdHTTPProtocolException do
    begin
      Result := e.ErrorMessage;   
      FreeAndNil(idhttps);
      FreeAndNil(sslIOHandler);
    end;

  End;
end;
// {$endregion}
2. POST 방식 일경우(http, https)

pURL --> https://도메인주소.com

 

sParam --> name=value

sParam01 -->name01=value01

pAuthorization -->  Authorization : 인증키 

//{$region 'Https/ Post방식'}
//pURL  : 웹주소( https://도메인주소.com)   
//sParam, sParam01 : 파라미터(name=value)
//pAuthorization  : 인증키(Authorization)
function HttpsPost(pURL, sParam, sParam01, pAuthorization : WideString) : WideString;
Var
  idhttps: TIdHTTP;
  sslIOHandler : TIdSSLIOHandlerSocketOpenSSL;
  lStream : TStringStream;
  sl : TStringList;
begin
  Try
    Result := '';
    idhttps := TIdHTTP.Create();
    lStream := TStringStream.Create(nil);
    sl := TStringList.Create;
    sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    Try
      sslIOHandler.SSLOptions.Method := sslvSSLv23;
      sslIOHandler.SSLOptions.Mode := sslmClient;
      idhttps.IOHandler := sslIOHandler;
      idhttps.Request.CustomHeaders.Add(pAuthorization);
      idhttps.HandleRedirects := False;
      idhttps.Request.Method := 'POST';
      idhttps.Response.ContentType := 'application/json; charset=utf-8';
      idhttps.ConnectTimeout := 5000;
      idhttps.ReadTimeout := 5000;      
      
      sl.Add(sParam);
      sl.Add(sParam01);     

      lStream.Position := 0;
      idhttps.Post(pURL,sl, lStream);
    Finally
      Result :=  TEncoding.UTF8.GetString(lStream.Bytes,0, lStream.Size);
      FreeAndNil(sl);
      FreeAndNil(lStream);
      FreeAndNil(idhttps);
      FreeAndNil(sslIOHandler);
    End;
  except
    on E: EIdHTTPProtocolException do
    begin
      Result := e.ErrorMessage;
      FreeAndNil(sl);
      FreeAndNil(lStream);
      FreeAndNil(idhttps);
      FreeAndNil(sslIOHandler);
    end;
  End;

end;
//{$endregion}

 

마무리

XE10.3.2에서 한글 깨지는 현상 없이 정상 처리 됩니다.

GET과 POST 두가지 방식  대해  적절한 용도로 사용하시면 됩니다.

 

이 글이 도움이 되었거나 마음에 든다면,
♥(공감)

눌러주세요!!

 

궁금한 부분이 있으시다면 댓글 달아주세요~

이 글을 공유하기

댓글(16)

  • 익명
    2020.08.04 08:49

    비밀댓글입니다

    • 2020.08.04 08:51 신고

      감사합니다... 예시입니다.. 하나또는 두개 이상 피라메티 넘길 수 있다는 예시 입니다 ^^

    • 2020.08.04 14:46

      데이터 포맷은 요청전문을 정의한 header 와 전달 파라미터를 정의한 body 조합의 JSON데이터라고 하는데
      요건 무슨말인지요?

    • 2020.08.04 15:01 신고

      관련 글 대해서는 API 가이드 따라
      요청 Parameter 따라 json형식 따라 Response 되는 소스 내용 입니다. 참고하셔서 API 문서의 맞게 응용하시면 되실 것 같습니다. 혹시 해당 잘 안 되는 부분 대해 알려주시면 간단히 샘플 소스 알려 드리겠습니다.
      감사합니다.

    • 2020.08.04 19:36

      그럼 올려주신 SPARAM=HEADER이고
      sparam01=body로 비교하면 될까요?
      api 포맷이 header과 body로 나누어져
      통신을 해야 하니까요

    • 2020.08.04 20:33 신고

      API 통신 하기 위해, client에서 API server로 URL정보를 넘길 때 데이터가 있을 경우에는 [name1=value1] 함께 싣어서 요청하시면 됩니다. 그리고, 서버단에서는 AIP 가이드 처럼 꼭 필요한 정보 대해서는 header에 적으시면 됩니다.
      그리고. 소스 내용처럼 이미 idhttps.Request.Method := 'POST'; 또는 idhttps.Request.Method := 'GET'; 타입으로 선언 되어서 API header정보 값만 넣으신다면 성공 하실 것 입니다. ^^

    • 2020.08.05 03:30

      THashSHA2를 사용해서 hash를 한문자열을 header에 실려 보내 볼려고 하는데
      system.hash를 uses절에 추가를 해도
      undeclared identifier가 나오네요 ㅠ
      구글에서 hash방법을 찾아서 그대로 해보는데요

    • 2020.08.05 08:11 신고

      음~ 그러시면 저에게 샘플 소스 전달해주시면 한 번 확인 해보겠습니다 kimyoungwoo@icloud.com

    • 2020.08.05 08:41

      procedure TForm1.Button1Click(Sender: TObject);
      var
      tempString : String;
      vHash : THashSHA2;

      begin
      try
      Readln(tempString);
      if tempString <> '' then begin
      Writeln('You Input String : ' + Format('%s',[tempString]) + #13#10
      + 'SHA256 Hash String : ' + Format('%s',[vHash.GetHashString(tempString,SHA256)]));
      end;

      Readln(tempString);
      except
      on E: Exception do //if ERROR Then u Can show ERROR CODE
      Writeln(E.ClassName, ': ', E.Message);
      end;
      end.

      샘플소스입니다
      제가 사용하는 del버전은 xe8이고요
      vHash : THashSHA2; 에서 THashSHA2가 undeclared identifier라고 에러가 나네요
      물론 uses절엔 system.hash를 포함했고요

      매번 감사합니다.
      요것만 넘기면 실제 text를 넣어서 함 돌려 보려고 했는데 말입니다 쩝

    • 2020.08.05 10:50 신고

      소스 내용 확인 결과, Readln 또는 Writeln 부분이 오류입니다. 왜냐하면 파일 입출력 기능 입니다. 저가 약간 변경하면 다음과 같습니다.
      uses System.Hash < 추가 후, 폼위에 edit1, edit2 텍스트 박스 올려 놓고 아래소스 참고 하시면 되실 것 같습니다.
      procedure TForm1.Button1Click(Sender: TObject);
      var
      tempString : String;
      vHash : THashSHA2;

      begin
      try
      Edit2.Text := '';
      tempString := Edit1.Text;

      if tempString <> '' then
      begin
      Edit2.Text := 'You Input String : ' + Format('%s',[tempString]) + #13#10
      + 'SHA256 Hash String : ' + Format('%s',[vHash.GetHashString(tempString,SHA256)]);
      end;

      //Readln(tempString);
      except
      on E: Exception do //if ERROR Then u Can show ERROR CODE
      ShowMessage(E.ClassName+ ': ' + e.Message);

      end;
      end;

    • 2020.08.05 14:22

      본샘플 자체의 문제가 아니라 분명히 uses 절에 system.Hash를 추가 했는데

      THashSHA2에서 undeclared identifier가 나오냐는 겁니다.

    • 2020.08.05 14:39 신고

      THashSHA2에서 undeclared identifier 발생한 이유 대해서는 함수를 블럭으로 선택 후 F1 키를 눌러 도움말을 참고 하시면 오류 부분 잡을 수 있을 것 같습니다. - 전 XE10.3 Rio에서 테스트 진행 했거든요..

      System.Hash 유닛 대해서는 XE8버전부터 지원 가능하죠..
      추가적으로
      XE8 -> MD5, SHA-1 및 Bob Jenkins 해시를 지원
      XE10.0 -> HA-2 지원으로 확장
      XE10.3 -> 바이트 입력 외에 문자열 또는 스트림을 허용하도록 해시 함수가 확장
      이정도까지만 저가 알고 있는 부분입니다.

    • 2020.08.06 09:00

      xe8버전에서는 TIdHashSHA2가 먹히지 않고 TIdHashSHA1만 되네요
      TIdHashSHA1도 sha256으로도 hash가 가능한가요?

    • 2020.08.06 09:26

      한가지만 더 질문하겠습니다.
      function GetSHA256Str(const str : Ansistring) : Ansistring;
      begin
      IdSSLOpenSSL.LoadOpenSSLLibrary;
      with TIdHashSHA256.Create do
      try
      Result := LowerCase( HashStringAsHex(str) );
      finally
      Free;
      end;
      IdSSLOpenSSL.UnLoadOpenSSLLibrary;
      end;


      procedure TForm1.Button1Click(Sender: TObject);
      var
      sid,dtm,mid,gkey:ansistring;
      begin
      mid:='king93940g';
      dtm:=formatdatetime('yyyymmddHHMMSS',now);
      gkey:='yH1NuGKuU6cCwy5vnyVXcoGNPGb1CQfGVpcoW+pR6miwR5NuHIC2b5CkekMKZIYZEL'
      showmessage(GetSHA256Str(sid+dtm+gkey));
      //Memo1.Text := GetSHA256Str(sid+dtm+gkey);
      end;

      했는데 결과가 access violation at address 00000000이 나오네요
      구글에 나오는 예제는 왠만하면 다 해 봤는데 아 힘드네요
      요건 왜 그런지 부탁드립니다

  • 송보근
    2020.10.07 17:05

    TEncode.UTF8.Getstring 부분은 uses 절에 어떤 것을 입력해야해요 ?
    델파이 7 사용하고있습니다 이버전에서는 없는걸까요 ?

    • 2020.10.07 17:41 신고

      델파이7버전에서 사용 불가능합니다. 별도로 function 만들어서 사용 해야 할 것 같습니다.