how to create jwt token base rest api lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Packs · 2023-08-30 05:56 how to implement jwt token in lazarus ---------------------------------------------------------------------- Packs · 2023-08-30 06:37 I am generating token in golang and I would like to validate the jwt token in lazarus pascal. ---------------------------------------------------------------------- nummer8 · 2023-08-30 06:45 In the trunk is an example on how to create and valiudate a jwt token https://gitlab.com/freepascal.org/fpc/source/-/tree/main/packages/fcl- web/examples/jwt ---------------------------------------------------------------------- delphius · 2023-08-30 06:47 Maybe use fpJWT? And look into this discussion. ---------------------------------------------------------------------- Packs · 2023-08-31 10:34 does any one is having jwt sample code . jwt creation and verification ---------------------------------------------------------------------- rvk · 2023-08-31 10:49 Quote from: Prakash on August 31, 2023, 12:34:06 pmdoes any one is having jwt sample code . jwt creation and verification Did you look at the links posted previously? Quote from: delphius on August 30, 2023, 08:47:31 amMaybe use fpJWT? And look into this discussion. ---------------------------------------------------------------------- Packs · 2023-08-31 10:59 Yes. it is having generation logic . I want both create and validate . ---------------------------------------------------------------------- Packs · 2023-08-31 11:03 I need to verify each and every api through jwt token , I need Jwt Create and validate . so please any one implement rest api with jwt token . please share the sample code ---------------------------------------------------------------------- rvk · 2023-08-31 11:51 Quote from: Prakash on August 31, 2023, 12:59:21 pmYes. it is having generation logic . I want both create and validate . Doesn't TMyJWT.ValidateJWT validate a jwt? ---------------------------------------------------------------------- Packs · 2023-08-31 17:14 function TFrmmain.GenJwt(issuer, subject, secret_key: String; minutesToExpire: Integer): String; var   jwt: TJWT;   LHMAC: IHMAC;   barr: TBytes;   s: String;   i: Integer; begin   jwt := TJWT.Create;   jwt.Claims.iss:= issuer;   jwt.Claims.exp:= DateTimeToUnix(IncMinute(Now, minutesToExpire));   jwt.Claims.sub:= subject;   jwt.JOSE.alg:= 'HS256';   jwt.JOSE.typ:= 'JWT';   Result := jwt.JOSE.AsEncodedString + '.' + jwt.Claims.AsEncodedString;   LHMAC := THashFactory.THMAC.CreateHMAC(THashFactory.TCrypto.CreateSHA2_256);   LHMAC.Key := TConverters.ConvertStringToBytes(secret_key, TEncoding.UTF8);   barr := LHMAC.ComputeString(Result, TEncoding.UTF8).GetBytes();   s := '';   for i := Low(barr) to High(barr) do     s := s + chr(barr);   jwt.Signature := jwt.Base64ToBase64URL(EncodeStringBase64(s));   Result := Result + '.' + jwt.Signature;   jwt.Free; end;  this code generate the jwt token but how to verify the token with rest api . ---------------------------------------------------------------------- rvk · 2023-08-31 17:49 Quote from: Prakash on August 31, 2023, 07:14:22 pmthis code generate the jwt token but how to verify the token with rest api . The code to verify would be something like this: ( TJWT.ValidateJWT is a class function of TJWT so you can call it directly, you don't need an instance of TJWT itself.) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i VerifyResult := TJWT.ValidateJWT(aInput, Key);if VerifyResult = nil then  raise Exception.Create('Verification failed!');VerifyResult.Free;  The example in the topic and wiki points to a complete example here: https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl- web/examples/jwt/signrs256.lpr In that source on line 140-143 the just create jwt is verified. (But as said... you can just feed the aInput and Key to TJWT.ValidateJWT too) (note: the example has some memory leaks but does show the verification process) ---------------------------------------------------------------------- Packs · 2023-09-01 08:01 I am using fpjwt unit TJWT = Class(TBaseJWT)   private     FClaims: TClaims;     FJOSE: TJOSE;     FSignature: String;     procedure SetClaims(AValue: TClaims);     procedure SetJOSE(AValue: TJOSE);   Protected     Function CreateJOSE : TJOSE; Virtual;     Function CreateClaims : TClaims; Virtual;     // AsString and AsEncodedString are the same in this case.     function GetAsString: TJSONStringType; override;     procedure SetAsString(AValue: TJSONStringType);override;     function GetAsEncodedString: String;override;     Procedure SetAsEncodedString (AValue : String);override;   Public     Constructor Create; override;     Destructor Destroy; override;     // Owned by the JWT. The JSON header.     Property JOSE : TJOSE Read FJOSE Write SetJOSE;     // Owned by the JWT. The set of claims. The actuall class will depend on the descendant.     Property Claims : TClaims Read FClaims Write SetClaims;     Property Signature : String Read FSignature Write FSignature;   end; This don't have verification code ---------------------------------------------------------------------- rvk · 2023-09-01 08:45 Quote from: Prakash on September 01, 2023, 10:01:41 amThis don't have verification code For me there is. You probably have an older version of FPC (and you didn't mention your versions of Lazarus and FPC). You can also see the latest source here: https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl- web/src/jwt/fpjwt.pp?ref_type=heads (ValidateJWT was added back in 2021 in FPC) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TJWT = Class(TBaseJWT)  private    FClaims: TClaims;    FJOSE: TJOSE;    FSignature: String;    procedure SetClaims(AValue: TClaims);    procedure SetJOSE(AValue: TJOSE);  Protected    Function CreateJOSE : TJOSE; Virtual;    Function CreateClaims : TClaims; Virtual;    // AsString and AsEncodedString are the same in this case.    function GetAsString: TJSONStringType; override;    procedure SetAsString(AValue: TJSONStringType);override;    function GetAsEncodedString: String;override;    Procedure SetAsEncodedString (AValue : String);override;  Public    Constructor Create; override;  Destructor Destroy; override;    Function Sign(aKey : TJWTKey) : String;    Class Function ValidateJWT(const aJWT : String; aKey : TJWTKey; aClass : TJWTClass = Nil) : TJWT;    // Owned by the JWT. The JSON header.    Property JOSE : TJOSE Read FJOSE Write SetJOSE;    // Owned by the JWT. The set of claims. The actual class will depend on the descendant.    Property Claims : TClaims Read FClaims Write SetClaims;    Property Signature : String Read FSignature Write FSignature;  end; ---------------------------------------------------------------------- paweld · 2023-09-01 08:45 this component allows to create and verify a jwt tokens: https://github.com/andre-djsystem/LazJWT ---------------------------------------------------------------------- Packs · 2023-09-01 13:56 Thanks. I will check ---------------------------------------------------------------------- Packs · 2023-09-04 04:51 Dear Team, I have used following library :  https://github.com/andre- djsystem/LazJWT. I have token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBYWRoYWFyIjoxMD AyLCJleHAiOjE2OTM5NzM5OTAsImlhdCI6MTY5MzgwMTE5MCwiaXNzIjoiUHJha2FzaCJ9 .rz2HQEJtwQyDcIVj_Je8hOg4d0PrTvseTglZlBFqS58 Secert key : chitranshkanuroopaprakash  when I try to verify it is saying signature invalid . Please help us what is the issue . ---------------------------------------------------------------------- paweld · 2023-09-04 05:05 show your code. ---------------------------------------------------------------------- Packs · 2023-09-04 05:35 var   LLazJWT: ILazJWT; begin   LLazJWT := TLazJWT.Create;   LLazJWT     .UseCustomPayLoad(true)     .Token("[size=0px]eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBYWRoYWF yIjoxMDAyLCJleHAiOjE2OTM5NzM5OTAsImlhdCI6MTY5MzgwMTE5MCwiaXNzIjoiUHJha 2FzaCJ9.rz2HQEJtwQyDcIVj_Je8hOg4d0PrTvseTglZlBFqS58[/size][/size][size =78%]")[/size][size=0px]     .SecretJWT("[/size][size=0px]chitranshkanuroopaprakash"[/size]);   mDecoded.Lines.Clear;   mDecoded.Lines.Add('HEADER');   mDecoded.Lines.Add('');   mDecoded.Lines.Add(LLazJWT.Header);   mDecoded.Lines.Add('');   mDecoded.Lines.Add('PAYLOAD');   mDecoded.Lines.Add('');   mDecoded.Lines.Add(LLazJWT.PayLoad);   mDecoded.Lines.Add('');   mDecoded.Lines.Add('AsString');   mDecoded.Lines.Add('');   mDecoded.Lines.Add(LLazJWT.AsString);   mDecoded.Lines.Add('');   mDecoded.Lines.Add('Signature '+IfThen(LLazJWT.ValidateSignature,'Verified','Invalid')); ---------------------------------------------------------------------- Packs · 2023-09-04 06:37 I have verified on https://jwt.io/ I have shared the image file too but through code it is showing invalid signature . ---------------------------------------------------------------------- rvk · 2023-09-04 07:05 Quote from: Prakash on September 04, 2023, 06:51:50 amwhen I try to verify it is saying signature invalid . Why didn't you follow the code I gave you with fpjwt ??? This just works fine.  (no mem leak with the destroy) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses fpjwt, fpjwasha256 { needs to be included for jwt to reach sha256 };//...var  VerifyResult: TJWT;  key: TJWTKey;  aInput: rawbytestring;begin  key.AsString := 'chitranshkanuroopaprakash';  aInput := 'eyJhbGciOiJIU zI1NiIsInR5cCI6IkpXVCJ9.eyJBYWRoYWFyIjoxMDAyLCJleHAiOjE2OTM5NzM5OTAsIm lhdCI6MTY5MzgwMTE5MCwiaXNzIjoiUHJha2FzaCJ9.rz2HQEJtwQyDcIVj_Je8hOg4d0P rTvseTglZlBFqS58';  VerifyResult := TJWT.ValidateJWT(aInput, Key);  if VerifyResult = nil then    Showmessage('No verify result, verification failed!')  else  begin    Showmessage('Valid key');    VerifyResult.Destroy;  end; ---------------------------------------------------------------------- Packs · 2023-09-04 07:09 Hi , I have reinstalled lazarus 2.2.6 and  FPC : 3.2.2 Still I am not getting Tjwt.Validate founction . so I can not implement your code . ---------------------------------------------------------------------- rvk · 2023-09-04 07:34 Quote from: Prakash on September 04, 2023, 09:09:56 amI have reinstalled lazarus 2.2.6 and  FPC : 3.2.2 Still I am not getting Tjwt.Validate founction . Ok, sorry. It seems like Lazarus/FPC is really way behind. FPC 3.2.2 is released on May 20th, 2021 and it seems these changes didn't make it in that release (as they were done on Nov 04, 2021 in trunk). ---------------------------------------------------------------------- Packs · 2023-09-04 07:45 How to install. Do you have link and procedure for the same ---------------------------------------------------------------------- rvk · 2023-09-04 08:08 Quote from: Prakash on September 04, 2023, 09:45:32 amHow to install. Do you have link and procedure for the same You would need to use a more recent development version (trunk). You could install that with fpcupdeluxe. But I'm not sure if it's worth the trouble (depending on your expertise level). You can wait to see if there are any reactions to the code for LazJWT and why that's not working. (it might be just a small thing but I'm not familiar with that code) ---------------------------------------------------------------------- paweld · 2023-09-04 09:18 LazJWT sorts the fields according to a specific scheme, so for token verification to be successful it must be created with LazJWT, or have the fields sorted according to the scheme: - iss - sub - aud - exp - nbf - iat - jti - other custom fields    for example:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var    token: String;    LLazJWT: ILazJWT;  begin      // create token    token := TLazJWT             .New             .SecretJWT('chitranshkanuroopaprakash')             .Exp(1693973990)             .Iat(1693801190)             .Iss('Prakash')             .AddClaim('Aadhaar', 1002)             .Token;      //verify token  LazJWT := TLazJWT.Create;  LLazJWT.Token(token)       .SecretJWT('chitranshkanuroopaprakash');    mDecoded.Lines.Add('Signature ' + IfThen(LLazJWT.ValidateSignature, 'Verified', 'Invalid')); ---------------------------------------------------------------------- Packs · 2023-09-04 13:23 I have installed from fpcupdeluxe-x86_64-win64 by using trunk still I can't able to find the code ---------------------------------------------------------------------- rvk · 2023-09-04 13:29 In trunk it should be definitely there. Can you tell me the size of the following file: fpc\packages\fcl-web\src\jwt\fpjwt.pp There should be a whole fpc\packages\fcl-web\src\jwt directory. My fpjwtt.pp is 20KB (19.611 bytes). ---------------------------------------------------------------------- Packs · 2023-09-04 13:46 I don't have JWT directory in C:\fpcupdeluxe\fpcsrc\packages\fcl- web\src inside SRC folder ---------------------------------------------------------------------- rvk · 2023-09-04 13:48 I wonder what version is installed then. From this site your can see that trunk (latest development version) as a jwt directory. https://gitlab.com/freepascal.org/fpc/source/-/tree/main/packages/fcl- web/src/jwt?ref_type=heads Edit: I just tried When select trunk for FPC and Lazarus you definitely get a jwt directory It's installing now and I see: C:\fpcupdeluxe\fpcsrc\packages\fcl- web\src\jwt ---------------------------------------------------------------------- nummer8 · 2023-09-04 14:47 Just to be sure. Use the trunk options at the top of the screen, in the columns FPC version and Lazarus version Then press Install/update FPC + Lazarus. I am not sure if the button trunk at the bottom will install the right version. (See attatchment) ---------------------------------------------------------------------- rvk · 2023-09-04 14:51 Quote from: nummer8 on September 04, 2023, 04:47:45 pmJust to be sure. Use the trunk options at the top of the screen, in the columns FPC version and Lazarus version Then press Install/update FPC + Lazarus. I am not sure if the button trunk at the bottom will install the right version. (See attatchment) Yes. Trunk at the top for both. Can you browse to C:\fpcupdeluxe\fpcsrc\packages\fcl-web\src\jwt ? If you can and it still doesn't work then it could be that you still have references to your old lazarus in your config. ---------------------------------------------------------------------- Packs · 2023-09-05 07:41 I have tried all options . it is not working for me . do you have any alternative options ---------------------------------------------------------------------- rvk · 2023-09-05 07:44 Quote from: Prakash on September 05, 2023, 09:41:48 amI have tried all options . it is not working for me . do you have any alternative options You have not told us if you have the C:\fpcupdeluxe\fpcsrc\packages\fcl-web\src\jwt directory? (after using "trunk" for both fpc and lazarus when installing fpcupdeluxe) The alternative is to use lazjwt (which is explained with a working example for verification on the previous page). ---------------------------------------------------------------------- delphius · 2023-09-05 08:02 Quote from: rvk on September 05, 2023, 09:44:25 amQuote from: Prakash on September 05, 2023, 09:41:48 amI have tried all options . it is not working for me . do you have any alternative options You have not told us if you have the C:\fpcupdeluxe\fpcsrc\packages\fcl-web\src\jwt directory? There is no time to explain and check, just give him the next solution ---------------------------------------------------------------------- Packs · 2023-09-06 07:01 Method 1 procedure TfrLazJWT.Button1Click(Sender: TObject); var   token: string;   LLazJWT: ILazJWT; begin   mDecoded.Lines.Clear;   try     TLazJWT       .New       .UseCustomPayLoad(true) //Set before Token       .Token('eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyAiaXNzIiA6ICJ QcmFrYXNoIiwgImV4cCIgOiAxNjk0MTU0OTk0LCAiaWF0IiA6IDE2OTM5ODIxOTQsICJBY WRoYWFyIiA6IDEwMDIgfQ.wKYbmmhwkAuuJ0FHkysuyXZ2JEcL9xFg3aD11H2rdN8')       .SecretJWT('chitranshkanuroopaprakash')       .ValidateToken;     mDecoded.Lines.Add('Token Verified');   except     On E: Exception do     begin       mDecoded.Lines.Add(E.Message);     end;   end; end;  Method 2 procedure TfrLazJWT.Button3Click(Sender: TObject); var   token: string;   LLazJWT: ILazJWT; begin   mDecoded.Lines.Clear;   try     TLazJWT       .New(TLazJWTConfig              .New              .IsRequiredSubject(False)              .IsRequiredIssuedAt(False)              .IsRequiredNotBefore(False)              .IsRequiredExpirationTime(False)              .IsRequireAudience(True)              .ExpectedAudience(['lazarus','djsystem'])              )       .UseCustomPayLoad(True) //Set before Token       .Token('eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyAiaXNzIiA6ICJ QcmFrYXNoIiwgImV4cCIgOiAxNjk0MTU0OTk0LCAiaWF0IiA6IDE2OTM5ODIxOTQsICJBY WRoYWFyIiA6IDEwMDIgfQ.wKYbmmhwkAuuJ0FHkysuyXZ2JEcL9xFg3aD11H2rdN8')       .SecretJWT('chitranshkanuroopaprakash')       .ValidateToken;     mDecoded.Lines.Add('Token Verified');   except     On E: Exception do     begin       mDecoded.Lines.Add(E.Message);     end;   end; end;  I have UseCustomPayLoad with false and true tried , still it is not verifying the token . ---------------------------------------------------------------------- Packs · 2023-09-06 07:11 What is issue in above code ---------------------------------------------------------------------- bytebites · 2023-09-06 07:34 Use code tags ---------------------------------------------------------------------- Packs · 2023-09-07 05:33 Dear Team, I have used https://github.com/andre-djsystem/LazJWT this library . I can able to create token and verify. I have other application which is written in golang by using this library ( "github.com/dgrijalva/jwt-go" ) I have to validate golang token in lazarus pascal. it is not validating . what will be the error . I have verfied ( https://jwt.io/ ) golang token on this website ---------------------------------------------------------------------- paweld · 2023-09-07 09:01 Sample in attachment, but: for security reasons, the correctness of the signature should be verified only by the issuer of the token - in order not to share the secret key. The recipient of the token can at most check the expiration date, or other values of the token, but should not know the secret key! ---------------------------------------------------------------------- Packs · 2023-09-07 10:30 Thanks for your support . I have modified your code . It is working for me now . Thanks so much. function TForm1.Validate(token, secret_key: String; onlySignatureCheck: Boolean; var msg: String): Boolean; var   LHMAC: IHMAC;   barr: TBytes;   newtoken, s: String;   i: Integer;   sarr: TStringArray;   function Base64ToBase64URL(AValue: string): string;   begin     Result := StringsReplace(AValue, ['+', '/'], ['-', '_'], [rfReplaceAll]);     Result := TrimRightSet(Result, ['=']);   end; begin   msg := '';   token := Trim(token);   (*   Result := False;   sarr := token.Split(['.'], TStringSplitOptions.ExcludeEmpty);   if Length(sarr) <> 3 then   begin     msg := 'Incorrect token';     exit;   end;   newtoken := sarr[0] + '.' + sarr[1];   LHMAC := THashFactory.THMAC.CreateHMAC(THashFactory.TCrypto.CreateSHA2_256);   LHMAC.Key := TConverters.ConvertStringToBytes(secret_key, TEncoding.UTF8);   barr := LHMAC.ComputeString(newtoken, TEncoding.UTF8).GetBytes();   s := '';   for i := Low(barr) to High(barr) do     s := s + chr(barr);   newtoken := newtoken + '.' + Base64ToBase64URL(EncodeStringBase64(s));   Result := token = newtoken;   *)   //if Result and not onlySignatureCheck then   //begin     newtoken := '';     newtoken := TLazJWT.New                   .Token(token)                   .SecretJWT(secret_key)                   .Token;     try       TLazJWT.New         .Token(newtoken)         .SecretJWT(secret_key)         .ValidateToken;     except       on E: Exception do       begin         msg := E.Message;         Result := False;       end;     end;   //end   //else end;