I've been trying to use the NetHTTPRequest
& NetHTTPClient
components in Delphi to issue a basic authentication request, but I've been having trouble with the NetHTTPRequest.Get
method...
Basically, the method needs three parameters, namely URL(String)
, memory stream, and the header of the type TNetHeader
.
I don't know why, but when I try to pass my newly created header, I get the error mentionned in the title, namely
Incompatible types: 'System.TArray<System.Net.URLClient.TNameValuePair>' and 'TNameValuePair'
I don't know if I have to cast, and If I have to, cast it to what?
Of course, If I don't pass on the basic auth header, the server just returns a 401 because it doesn't see any credentials or header to decode...
Here is the code :
procedure TForm1.Button1Click(Sender: TObject);
var
HTTPResponseString: String;
begin
if IsLoggedIn = False then
begin
if Edit2.Text = '' then
begin
ShowMessage('Password cannot be empty');
exit;
end;
BasicAuth := username ':' Edit2.Text; // '£';
AuthentificationPacket := EncodeBase64(UTF8Bytes(utf8string(BasicAuth)));
HTTPHeader := TNetHeader.Create('Authorization: Basic', AuthentificationPacket);
try
HTTPResponseLogin := NetHTTPRequest1.Get(HTTPLoginRequest, nil, HTTPHeader);
ShowMessage(HTTPResponselogin.ContentAsString());
IsLoggedIn := True;
except
on E: Exception do
ShowMessage(E.Message);
end;
Button1.Text := 'LOG OFF';
end
else if IsLoggedIn then
begin
Edit1.Text := '';
Edit2.Text := '';
username := '';
password := '';
tagid := '';
Button1.Enabled := False;
Button1.Text := 'LOG IN';
IsLoggedIn := False;
Timer1.Enabled := False;
IdleTimer := 0;
Application.OnIdle := nil;
end;
end;
The problematic line is of course, the NetHTTPRequest1.Get(HTTPLoginRequest, nil, HTTPHeader);
Where HTTPHeader
is marked as incompatible...
Any help is appreciated!
CodePudding user response:
Look at the declaration of TNetHTTPRequest.Get()
more carefully:
function Get(const AURL: string; const AResponseContent: TStream = nil; const AHeaders: TNetHeaders = nil): IHTTPResponse;
The 3rd parameter takes a TNetHeaders
(plural), but you are passing it a TNetHeader
(singular) instead. It wants an array of name/value pairs.
Also, Basic
is not part of an Authorization
header's name, it is part of its value instead.
Try something more like this:
procedure TForm1.Button1Click(Sender: TObject);
var
BasicAuth, AuthentificationPacket: string;
HTTPHeader: TNetHeader;
begin
if not IsLoggedIn then
begin
if Edit2.Text = '' then
begin
ShowMessage('Password cannot be empty');
Exit;
end;
BasicAuth := username ':' Edit2.Text; // '£';
AuthentificationPacket := 'Basic ' EncodeBase64(UTF8Bytes(UTF8String(BasicAuth)));
HTTPHeader := TNetHeader.Create('Authorization', AuthentificationPacket);
try
ShowMessage(NetHTTPRequest1.Get(HTTPLoginRequest, nil, [HTTPHeader]).ContentAsString());
except
on E: Exception do begin
ShowMessage(E.Message);
Exit;
end;
end;
IsLoggedIn := True;
Button1.Text := 'LOG OFF';
end
else
begin
Edit1.Text := '';
Edit2.Text := '';
username := '';
password := '';
tagid := '';
Button1.Enabled := False;
Button1.Text := 'LOG IN';
IsLoggedIn := False;
Timer1.Enabled := False;
IdleTimer := 0;
Application.OnIdle := nil;
end;
end;
Alternatively, you can use the TNetHTTPRequest.CustomHeaders
property instead of the AHeaders
parameter:
procedure TForm1.Button1Click(Sender: TObject);
var
BasicAuth: string;
begin
if not IsLoggedIn then
begin
if Edit2.Text = '' then
begin
ShowMessage('Password cannot be empty');
Exit;
end;
BasicAuth := username ':' Edit2.Text; // '£';
NetHTTPRequest1.CustomHeaders['Authorization'] := 'Basic ' EncodeBase64(UTF8Bytes(UTF8String(BasicAuth));
try
ShowMessage(NetHTTPRequest1.Get(HTTPLoginRequest).ContentAsString());
except
on E: Exception do begin
ShowMessage(E.Message);
Exit;
end;
end;
IsLoggedIn := True;
Button1.Text := 'LOG OFF';
end
else
begin
Edit1.Text := '';
Edit2.Text := '';
username := '';
password := '';
tagid := '';
Button1.Enabled := False;
Button1.Text := 'LOG IN';
IsLoggedIn := False;
Timer1.Enabled := False;
IdleTimer := 0;
Application.OnIdle := nil;
end;
end;