{"id":19133616,"url":"https://github.com/hashload/horse-jwt","last_synced_at":"2026-02-26T09:44:03.389Z","repository":{"id":40775459,"uuid":"151342992","full_name":"HashLoad/horse-jwt","owner":"HashLoad","description":"Middleware for JWT in HORSE","archived":false,"fork":false,"pushed_at":"2023-10-09T16:51:12.000Z","size":172,"stargazers_count":62,"open_issues_count":2,"forks_count":26,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-14T00:25:39.799Z","etag":null,"topics":["auth","authentication","horse","horse-jwt","jwt","middleware","token"],"latest_commit_sha":null,"homepage":null,"language":"Pascal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HashLoad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-10-03T00:48:01.000Z","updated_at":"2024-01-20T15:16:02.000Z","dependencies_parsed_at":"2023-10-11T06:58:42.458Z","dependency_job_id":null,"html_url":"https://github.com/HashLoad/horse-jwt","commit_stats":{"total_commits":84,"total_committers":18,"mean_commits":4.666666666666667,"dds":0.6309523809523809,"last_synced_commit":"8a9acf3663730a25d00fcb6608d1130d1f0d95e2"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HashLoad%2Fhorse-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HashLoad%2Fhorse-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HashLoad%2Fhorse-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HashLoad%2Fhorse-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HashLoad","download_url":"https://codeload.github.com/HashLoad/horse-jwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240214566,"owners_count":19766263,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auth","authentication","horse","horse-jwt","jwt","middleware","token"],"created_at":"2024-11-09T06:23:08.430Z","updated_at":"2025-11-13T09:01:57.338Z","avatar_url":"https://github.com/HashLoad.png","language":"Pascal","readme":"# Horse-JWT\n\u003cb\u003eHorse-JWT\u003c/b\u003e is an official middleware for generating and validating \u003ca href=\"https://jwt.io/\"\u003eJWTs\u003c/a\u003e in APIs developed with the \u003ca href=\"https://github.com/HashLoad/horse\"\u003eHorse\u003c/a\u003e framework.\n\u003cbr\u003eWe created a channel on Telegram for questions and support:\u003cbr\u003e\u003cbr\u003e\n\u003ca href=\"https://t.me/hashload\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/telegram-join%20channel-7289DA?style=flat-square\"\u003e\n\u003c/a\u003e\n\n## ⭕ Prerequisites\n##### Delphi\n- [**delphi-jose-jwt**](https://github.com/paolo-rossi/delphi-jose-jwt) - JOSE is a standard that provides a general approach to the signing and encryption of any content.\n\n##### Lazarus\n- [**hashlib4pascal**](https://github.com/andre-djsystem/hashlib4pascal) - is an Object Pascal hashing library released under the permissive MIT License which provides an easy to use interface for computing hashes and checksums of data. It also supports state based (incremental) hashing.\n\n\n## ⚙️ Installation\nInstallation is done using the [`boss install`](https://github.com/HashLoad/boss) command:\n``` sh\nboss install horse-jwt\n```\nIf you choose to install manually, simply add the following folders to your project, in *Project \u003e Options \u003e Resource Compiler \u003e Directories and Conditionals \u003e Include file search path*\n\n##### Delphi\n```\n../horse-jwt/src\n../delphi-jose-jwt/Source/Common\n../delphi-jose-jwt/Source/JOSE\n```\n\n##### Lazarus\n```\n../horse-jwt/src\n../HashLib/src/Base\n../HashLib/src/Checksum\n../HashLib/src/Crypto\n../HashLib/src/Hash128\n../HashLib/src/Hash32\n../HashLib/src/Hash64\n../HashLib/src/Include\n../HashLib/src/Interfaces\n../HashLib/src/KDF\n../HashLib/src/NullDigest\n../HashLib/src/Nullable\n../HashLib/src/Packages\n../HashLib/src/Utils\n```\n\n## ✔️ Compatibility\nThis middleware is compatible with projects developed in:\n- [X] Delphi\n- [X] Lazarus\n\n## ⚡️ Quickstart Delphi\n\n#### All requests need token authorization.\n\n```delphi\nuses Horse, Horse.JWT;\n\nbegin\n  THorse.Use(HorseJWT('MY-PASSWORD')); \n\n  THorse.Post('ping',\n    procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n    begin\n      Res.Send('pong');\n    end);\n\n  THorse.Listen(9000);\nend.\n```\n\n#### Some routes require authentication\n\n```delphi\nuses Horse, Horse.JWT;\n\nbegin\n  THorse.Get('ping',\n    procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n    begin\n      Res.Send('pong');\n    end);\n\n  THorse\n    .AddCallback(HorseJWT('MY-PASSWORD'))\n    .Get('private',\n      procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n      begin\n        Res.Send('route private');\n      end);\n\n  THorse.Listen(9000);\nend.\n```\n\n#### Skip routes\n\n```delphi\nuses Horse, Horse.JWT;\n\nbegin\n  THorse.Use(HorseJWT('MY-PASSWORD', THorseJWTConfig.New.SkipRoutes(['public'])));\n\n  THorse.Get('public',\n    procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n    begin\n      Res.Send('public route');\n    end);\n\n  THorse.Get('private',\n    procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n    begin\n      Res.Send('private route');\n    end);\n\n  THorse.Listen(9000);\nend.\n```\n\n## Usage samples\n\n#### How to create the token?\n\n```delphi\nuses\n  Horse, Horse.JWT,\n  JOSE.Core.JWT, JOSE.Core.Builder,\n  System.DateUtils, System.SysUtils;\n\nbegin\n  THorse.Post('create-token',\n    procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n    var\n      LJWT: TJWT;\n      LToken: String;\n    begin\n      LJWT := TJWT.Create();\n      try\n        // Enter the payload data\n        LJWT.Claims.Expiration := IncHour(Now, 1);\n\n        // Generating the token\n        LToken := TJOSE.SHA256CompactToken('MY-PASSWORD', LJWT);\n      finally\n        FreeAndNil(LJWT);\n      end;\n\n      // Sending the token\n      Res.Send(LToken);\n    end);\n\n  THorse.Listen(9000);\nend.\n```\n\n#### How to create a custom Payload?\n\n* Here is an example of a custom payload class.\n* For the following examples, it is necessary to use this class.\n\n```delphi\nunit MyClaims;\n\ninterface\n\nuses\n  JOSE.Core.JWT, JOSE.Types.JSON;\n\ntype\n  TMyClaims = class(TJWTClaims)\n  strict private\n    function GetId: string;\n    procedure SetId(const Value: string);\n    function GetName: string;\n    procedure SetName(const Value: string);\n    function GetEmail: string;\n    procedure SetEmail(const Value: string);\n  public\n    property Id: string read GetId write SetId;\n    property name: string read GetName write SetName;\n    property Email: string read GetEmail write SetEmail;\n  end;\n\nimplementation\n\n{ TMyClaims }\n\nfunction TMyClaims.GetId: string;\nbegin\n  Result := TJSONUtils.GetJSONValue('id', FJSON).AsString;\nend;\n\nprocedure TMyClaims.SetId(const Value: string);\nbegin\n  TJSONUtils.SetJSONValueFrom\u003cstring\u003e('id', Value, FJSON);\nend;\n\nfunction TMyClaims.GetName: string;\nbegin\n  Result := TJSONUtils.GetJSONValue('name', FJSON).AsString;\nend;\n\nprocedure TMyClaims.SetName(const Value: string);\nbegin\n  TJSONUtils.SetJSONValueFrom\u003cstring\u003e('name', Value, FJSON);\nend;\n\nfunction TMyClaims.GetEmail: string;\nbegin\n  Result := TJSONUtils.GetJSONValue('email', FJSON).AsString;\nend;\n\nprocedure TMyClaims.SetEmail(const Value: string);\nbegin\n  TJSONUtils.SetJSONValueFrom\u003cstring\u003e('email', Value, FJSON);\nend;\n\nend.\n```\n\n#### How to create a token with the custom payload?\n\n```delphi\nuses\n  Horse, Horse.JWT,\n\n  MyClaims in 'MyClaims.pas',\n\n  JOSE.Core.JWT, JOSE.Core.Builder,\n  System.DateUtils, System.SysUtils;\n\nbegin\n  THorse.Post('create-token',\n  procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n  var\n    LJWT: TJWT;\n    LClaims: TMyClaims;\n    LToken: String;\n  begin\n    // Add the class\n    LJWT := TJWT.Create(TMyClaims);\n    try\n      // Casting using the class\n      LClaims := TMyClaims(LJWT.Claims);\n\n      // Enter the payload data\n      LClaims.Expiration := IncHour(Now, 1);\n      LClaims.Id := '1';\n      LClaims.Name := 'Horse';\n      LClaims.Email := 'horse@jwt.com';\n\n      // Generating the token\n      LToken := TJOSE.SHA256CompactToken('MY-PASSWORD', LJWT);\n    finally\n      FreeAndNil(LJWT);    \n    end;\n\n    // Sending the token\n    Res.Send(LToken);\n  end);\n\n  THorse.Listen(9000);\nend.\n```\n\n#### How to read the custom Payload?\n\n```Delphi\nuses\n  Horse, Horse.JWT,\n  MyClaims in 'MyClaims.pas',\n  System.SysUtils;\n\nbegin\n  THorse\n    .AddCallback(HorseJWT('MY-PASSWORD', THorseJWTConfig.New.SessionClass(TMyClaims))) // Add custom payload class\n    .Get('ping', \n      procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n      var\n        LClaims: TMyClaims;\n        LId, LName, LEmail: string;\n      begin\n        // Get the Payload information from the Session\n        LClaims := Req.Session\u003cTMyClaims\u003e;\n\n        LId := LClaims.Id;\n        LName := LClaims.Name;\n        LEmail := LClaims.Email;\n\n        Res.Send(Format('I’m %s and this is my email %s',[LName, LEmail]));\n      end);\n\n  THorse.Listen(9000);\nend.\n```\n\n#### How to create public and private routes?\n\n```Delphi\nuses\n  Horse, Horse.JWT,\n\n  MyClaims in 'MyClaims.pas',\n\n  JOSE.Core.JWT, JOSE.Core.Builder,\n  System.DateUtils, System.SysUtils;\n\nbegin\n  // Create token\n  THorse.Post('create-token',\n    procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n    var\n      LJWT: TJWT;\n      LClaims: TMyClaims;\n      LToken: String;\n    begin\n      // Add the class\n      LJWT := TJWT.Create(TMyClaims);\n      try\n        // Casting using the class\n        LClaims := TMyClaims(LJWT.Claims);\n\n        // Enter the payload data\n        LClaims.Expiration := IncHour(Now, 1);\n        LClaims.Id := '1';\n        LClaims.Name := 'Horse';\n        LClaims.Email := 'horse@jwt.com';\n\n        // Generating the token\n        LToken := TJOSE.SHA256CompactToken('MY-PASSWORD', LJWT);\n      finally\n        FreeAndNil(LJWT);\n      end;\n\n      // Sending the token\n      Res.Send(LToken);\n    end);\n\n  // Route public\n  THorse.Get('public',\n    procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n    begin\n      Res.Send('Route public');\n    end);\n\n  // Route private\n  THorse\n    .AddCallback(HorseJWT('MY-PASSWORD', THorseJWTConfig.New.SessionClass(TMyClaims))) // Add custom payload class  \n    .Get('private', \n      procedure(Req: THorseRequest; Res: THorseResponse; Next: TProc)\n      var\n        LClaims: TMyClaims;\n        LId, LName, LEmail: string;\n      begin\n        // Get the Payload information from the Session\n        LClaims := Req.Session\u003cTMyClaims\u003e;\n\n        LId := LClaims.Id;\n        LName := LClaims.Name;\n        LEmail := LClaims.Email;\n\n        Res.Send(Format('I’m %s and this is my email %s', [LName, LEmail]));\n      end);\n\n  THorse.Listen(9000);\nend.\n```\n\n## ⚡️ Quickstart Lazarus\n\n#### All requests need token authorization.\n\n```delphi\n{$MODE DELPHI}{$H+}\n\nuses\n  {$IFDEF UNIX}{$IFDEF UseCThreads}\n  cthreads,\n  {$ENDIF}{$ENDIF}\n  Horse, Horse.JWT, SysUtils;\n\nprocedure GetPing(Req: THorseRequest; Res: THorseResponse; Next: TNextProc);\nbegin\n  Res.Send('Pong');\nend;\n\nbegin\n  THorse.Use(HorseJWT('my-private-key'));\n\n  THorse.Get('/ping', GetPing);\n\n  THorse.Listen(9000);\nend.\n```\n\n#### Some routes require authentication\n\n```delphi\n{$MODE DELPHI}{$H+}\n\nuses\n  {$IFDEF UNIX}{$IFDEF UseCThreads}\n  cthreads,\n  {$ENDIF}{$ENDIF}\n  Horse, Horse.JWT, SysUtils;\n\nprocedure GetPing(Req: THorseRequest; Res: THorseResponse; Next: TNextProc);\nbegin\n  Res.Send('Pong');\nend;\n\nprocedure GetPrivate(Req: THorseRequest; Res: THorseResponse; Next: TNextProc);\nbegin\n  Res.Send('route private');\nend;\n\nbegin\n  THorse.Get('/ping', GetPing);\n  \n  THorse\n    .AddCallback(HorseJWT('my-private-key'))\n    .Get('private', GetPrivate);\n\n  THorse.Listen(9000);\nend.\n```\n\n## ⚠️ License\n`horse-jwt` is free and open-source middleware licensed under the [MIT License](https://github.com/HashLoad/horse-jwt/blob/master/LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashload%2Fhorse-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhashload%2Fhorse-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashload%2Fhorse-jwt/lists"}