How to clear the Indy TIdHTTP BasicAuthentication credentials?

回眸只為那壹抹淺笑 提交于 2019-12-13 02:22:15

问题


I'm using the Indy TIdHTTP for get request with BasicAuthentication.

Code working fine, but TIdHTTP doesn't clearing the BasicAuthentication credentials after first 401, if user retype the credentials and send request again, with right login-password. User must login twice to authorize.

User action sequence:

Step 1. User type wrong login-password: ResponseCode = 401

Step 2. User type right login-password: ResponseCode = 401

Step 3. User type right login-password: ResponseCode = 200

Result on Step 2 is a bug, I think. What should I do?

Simple code:

var
IdHTTP1: TIdHTTP;

fLogin : string;
fPassword : string;

/// ...

if ( fLogin <> '' ) and ( fPassword <> '' )
  then
    begin
    if ( IdHTTP1.Request.Username <> fLogin )
        or
       ( IdHTTP1.Request.Password <> fPassword )
      then
        begin  
          IdHTTP1.Request.BasicAuthentication := True;
          IdHTTP1.Request.Username := fLogin;
          IdHTTP1.Request.Password := fPassword;
        end;

      s := IdHTTP1.Get( 'some_url' );          
      response_code := Idhttp1.response.ResponseCode;

      case response_code of
        200:
          begin
               // parse request data
          end;
        401 : Result := nc_res_Auth_Fail;
        else Result := nc_res_Fail;
       end;
end;

回答1:


You should clear your authentication before change

  if Assigned(IdHTTP1.Request.Authentication) then
    begin
      IdHTTP1.Request.Authentication.Free;
      IdHTTP1.Request.Authentication:=nil;
    end;

or you can change it this way

  if Assigned(IdHTTP1.Request.Authentication) then
    begin
      IdHTTP1.Request.Authentication.Username:=...;
      IdHTTP1.Request.Authentication.Password:=...;
    end else
    begin
      IdHTTP1.Request.BasicAuthentication:=True;
      IdHTTP1.Request.Username:=...;
      IdHTTP1.Request.Password:=...;
    end;



回答2:


You should set the Request.UserName and Request.Password properties on each request, and then use the OnAuthorization event to retrieve new credentials if the server asks for them, eg:

procedure TSomeClass.HttpAuthorization(Sender: TObject; Authentication: TIdAuthentication; var Handled: Boolean);
begin
  if GetNewCredentials() then
  begin
    Authentication.UserName := ...;
    Authentication.Password := ...;
    Handled := True;
  end;
end;

//...

var
  IdHTTP1: TIdHTTP;
  fLogin : string;
  fPassword : string;

// ...

  IdHTTP1.OnAuthorization := HttpAuthorization;

  IdHTTP1.Request.BasicAuthentication := True;
  IdHTTP1.Request.Username := fLogin;
  IdHTTP1.Request.Password := fPassword;

  s := IdHTTP1.Get( 'some_url' );          
  response_code := IdHTTP1.Response.ResponseCode;

  case Response_Code of
    200:
      begin
        // parse request data
      end;
    401 : Result := nc_res_Auth_Fail;
  else
    Result := nc_res_Fail;
  end;
end;

TIdHTTP will internally keep re-trying login, triggering OnAuthorization each time, until the server stops sending a 401 reply or TIdHTTP.MaxAuthRetries has been reached, whichever occurs first.



来源:https://stackoverflow.com/questions/30076775/how-to-clear-the-indy-tidhttp-basicauthentication-credentials

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!