Voici la traduction en anglais de votre texte. Il est formaté de manière à pouvoir être copié-collé directement sur un forum anglophone (comme le support de TMS) :
Here is my problem:
After a successful WEB client authentication, and once the client has stored the token returned by the server in the "localStorage", when the second call to load the table is sent to the server—making sure to add the value "Authorization = Bearer XXXXx" to the header—the server responds with a 401 "Unauthorized" message.
The code to add the token to the request is as follows:
Delphi
/*
procedure TwfMain.XDataWebConnection1Request(Args: TXDataWebConnectionRequest);
begin
if GetToken <> '' then
Args.Request.Headers.SetValue('Authorization', 'Bearer ' + GetToken);
end;
*/
The GetToken function correctly returns the token sent by the server.
Every call to the server goes through the following code:
Delphi
/*
procedure TServerContainer.XDataServerGenericRequest(Sender: TObject;
Context: THttpServerContext; Next: THttpServerProc);
var
LastSegment: string;
begin
LastSegment := '';
if (Length(Context.Request.Uri.Segments) > 0) then
LastSegment := Context.Request.Uri.Segments[Length(Context.Request.Uri.Segments) - 1];
LastSegment := LowerCase(LastSegment);
// Unless user is trying to login or create user, forbid any access to the API without a token
if (Context.Request.User = nil) and (LastSegment <> 'login') and (LastSegment <> '$model') then
begin
Context.Response.StatusCode := 401;
Context.Response.ContentType := 'text/plain';
Context.Response.Close(TEncoding.UTF8.GetBytes('Unauthorized'));
end
else
Next(Context);
end;
*/
On the second call, the Context.Request.User property should contain the user credentials added to the token with the following function:
Delphi
/*
function TAGILadService.Login(const UserName, Password: string): string;
var
JWT: TJWT;
Abonne: TAbonne;
begin
// Check if UserName and Password are valid
Abonne := TXDataOperationContext.Current.GetManager.Find<TAbonne>
.Where((Linq['Login'] = UserName) and (Linq['Mdp'] = Password))
.UniqueResult;
if Abonne = nil then
raise EXDataHttpException.Create(400, 'Invalid user name or password.');
// Now that application specific logic is finished, generate the token
JWT := TJWT.Create(TJWTClaims);
try
JWT.Claims.Issuer := 'Agisoft LAD Server';
JWT.Claims.SetClaimOfType<Integer>('userId', Abonne.Id);
JWT.Claims.Expiration := Now + 1; // 1 day expiration
Result := TJOSE.SHA256CompactToken(JWTSecret, JWT);
finally
JWT.Free;
end;
end;
*/
However, it is always nil, which results in my 401 response code.
On the WEB client side, the response to the login in the console is as follows:
JSON
{
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJBZ2lzb2Z0IExBRCBTZXJ2ZXIiLCJ1c2VySWQiOjU5MywiZXhwIjoxNzg2MDI2OTkxfQ.G1IXOUZ2Kc2SoCUbE7BVGMqRmyPRaLqusXTEevUKWIg"
}
Loading the table with the following URL:
Request URL: http://localhost:2002/tms/xdata/AbonneCriee
Request Method: GET
Request Headers:
HTTP
GET /tms/xdata/AbonneCriee HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7,la;q=0.6
Connection: keep-alive
Host: localhost:2002
Origin: http://127.0.0.1:8000
Referer: http://127.0.0.1:8000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Linux; Android 15; Pixel 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Mobile Safari/537.36
authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJBZ2lzb2Z0IExBRCBTZXJ2ZXIiLCJ1c2VySWQiOjU5MywiZXhwIjoxNzg2MDMwOTk4fQ._1Dc7H_8wYq0gTuQtLVGRt-QxjY_ZTR7Kgy3-2nI43c
sec-ch-ua: "Not;A=Brand";v="8", "Chromium";v="150", "Google Chrome";v="150"
sec-ch-ua-mobile: ?1
sec-ch-ua-platform: "Android"