问题
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