2012-07-31 5 views
1

누구나 올바른 방향을 가리킬 수 있습니까? 새로운 Bing API를 사용하여 웹 검색을 수행하려고하는데 아래 코드를 사용하여 계속 "HTTP/1.1 400 Bad Request"를 얻습니다. 동일한 요청은 브라우저에서 잘 작동합니다 (사용자 이름을 공란으로 남겨두고 프롬프트 상자 안에 암호로 키를 제공).Bing Search API Azure Marketplace 인증 (Delphi + Indy)

var 
    IdHTTP1 : TIdHTTP; 
    uri : string; 
    myIOhandler : TIdSSLIOHandlerSocketOpenSSL; 
begin 
    myIOhandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); 
    with myIOhandler do 
    begin 
     SSLOptions.Method := sslvTLSv1; 
     SSLOptions.Mode := sslmUnassigned; 
     SSLOptions.VerifyMode := []; 
     SSLOptions.VerifyDepth := 0; 
     host := ''; 
    end; 

    IdHTTP1:= TIdHTTP.Create(nil); 
    IdHTTP1.Request.UserAgent:= 'Mozilla/3.0 (compatible; IndyLibrary)'; 
    IdHTTP1.Request.Accept := 'text/javascript'; 
    IdHTTP1.Request.ContentType := 'application/json'; 
    IdHTTP1.Request.ContentEncoding := 'utf-8'; 

    IdHTTP1.HandleRedirects:= True; 
    IdHTTP1.ConnectTimeout:= 10000; 
    IdHTTP1.ReadTimeout:= 10000; 
    IdHTTP1.Request.CacheControl := 'no-cache'; 
    IdHTTP1.Request.BasicAuthentication:= True; 
    IdHTTP1.Request.Authentication:= TIdBasicAuthentication.Create; 
    IdHTTP1.Request.Authentication.Username:= ''; 
    IdHTTP1.Request.Authentication.Password:= APIKey;//Encode64(APIKey);//Encode64(APIKey+':'+APIKey) 
    IdHTTP1.IOHandler:= myIOHandler; 

    uri:= 'https://api.datamarket.azure.com/Bing/SearchWeb/Web?'+ 
      'Query=%27'+ query_text +'%27&$format=JSON&$top=50&$skip=0'; 
    s:= IdHTTP1.Get(uri); 

MS 설명서가 매우 좋지 않습니다.

+0

HTTP 기본 인증이 빈 사용자 이름으로 작동해야합니까? query_text가 올바르게 "URL 인코딩 됨"입니까? – mjn

+0

마이그레이션 가이드 문서에 따르면 : "사용자 이름 필드를 비워두고 암호 필드에 계정 키를 입력하십시오." –

+0

테스트를 위해 인코딩이 필요한 문자를 사용하고 있지 않습니다. 나는 나중에 다룰 것이다. 동일한 문자열이 브라우저에서 작동합니다. –

답변

3

TIdHTTP 당신을 위해 Basic 인증을 자동으로 처리합니다. 간단히 IdHTTP1.Request.BasicAuthentication := True을 입력하고 IdHTTP1.Request.UsernameIdHTTP1.Request.Password 속성을 입력하십시오. TIdBasicAuthentication을 직접 처리 할 필요가 없습니다.

NTLM과 같은 다른 인증을 지원하려면 uses 절에 relabant IdAuthentication... 단위 또는 IdAllAuthentication 단위를 간단히 추가하십시오.

Indy가 기본적으로 지원하지 않는 사용자 지정 인증을 지원하려는 경우 사용자 지정 TIdAuthentication 유도 클래스를 구현할 수도 있습니다. RegisterAuthenticationMethod()을 호출하여 TIdHTTP이 사용자 정의 클래스를 자동으로 사용할 수 있도록하거나 TIdHTTP.OnSelectAuthorization 이벤트를 사용하여 요청별로 수동으로 클래스를 할당 할 수 있습니다.

1

나는이 문제가 사용자 이름에 있다고 생각한다. 기본 인증을 사용하면 다음과 같다 헤더 보내야 : 사용자 이름이 귀하의 경우 비어

Authorization: Basic BASE64ENC(username:password) 

이후를, 당신은 실제로이를 보내는 : 문서 떠나라고

Authorization: Basic BASE64ENC(:password) 

에도 불구하고 사용자 이름을 비워두면 브라우저를 통해 페이지를 방문 할 때만 적용됩니다. 문서의 끝으로 코드 샘플에서보세요, 당신은 사용자 이름과 암호를 모두 계정의 열쇠 그 많은 예에서 것을 볼 수 있습니다 : 나는 당신이 동일한 작업을 수행 제안

bingContainer.Credentials = new NetworkCredential(accountKey, accountKey); 

당신의 코드 :

IdHTTP1.Request.Authentication:= TIdBasicAuthentication.Create; 
IdHTTP1.Request.Authentication.Username:= APIKey; 
IdHTTP1.Request.Authentication.Password:= APIKey; 
+0

제안 해 주셔서 감사합니다. 작동하지 않습니다. OpenSSL 라이브러리를 대체하고 SSL 옵션을 사용하여 조정할 것입니다. 아마도 그 패키지와 관련이 있습니다. –

+2

TIdHTTP가 자동으로 기본 인증을 처리합니다. 간단히'IdHTTP1.Request.BasicAuthentication : = True'를 설정하고'IdHTTP1.Request.Username'과'IdHTTP1.Request.Password' 속성을 채우십시오.'TIdBasicAuthentication'을 직접 처리 할 필요는 없습니다. –

+0

@RemyLebeau : 성공했습니다! 대답으로 게시 해주세요. –

관련 문제