{"id":16464479,"url":"https://github.com/deatil/larke-jwt","last_synced_at":"2026-02-13T22:01:55.710Z","repository":{"id":57010765,"uuid":"317005401","full_name":"deatil/larke-jwt","owner":"deatil","description":"A library to work with JSON Web Token and JSON Web Signature.","archived":false,"fork":false,"pushed_at":"2025-02-25T10:38:21.000Z","size":102,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-25T11:41:29.970Z","etag":null,"topics":["ecdsa","eddsa","hmac","json-web-signature","jws","jwt","jwt-token","php","rsa"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deatil.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,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-11-29T17:29:18.000Z","updated_at":"2025-02-25T10:36:20.000Z","dependencies_parsed_at":"2024-03-14T05:29:45.690Z","dependency_job_id":"13ca0623-e932-45fd-99fd-a5f74b212509","html_url":"https://github.com/deatil/larke-jwt","commit_stats":{"total_commits":41,"total_committers":1,"mean_commits":41.0,"dds":0.0,"last_synced_commit":"77ff034f80b055c5f78785c261e1484756b922ed"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deatil%2Flarke-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deatil%2Flarke-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deatil%2Flarke-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deatil%2Flarke-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deatil","download_url":"https://codeload.github.com/deatil/larke-jwt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241013995,"owners_count":19894179,"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":["ecdsa","eddsa","hmac","json-web-signature","jws","jwt","jwt-token","php","rsa"],"created_at":"2024-10-11T11:27:58.115Z","updated_at":"2026-02-13T22:01:55.655Z","avatar_url":"https://github.com/deatil.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JWT\n\nA simple library to work with JSON Web Token and JSON Web Signature (requires PHP 5.6+).\nThe implementation is based on the [RFC 7519](https://tools.ietf.org/html/rfc7519).\n\n\n## Installation\n\nyou can install it using [Composer](http://getcomposer.org).\n\n```shell\ncomposer require lake/larke-jwt\n```\n\n### Dependencies\n\n- PHP \u003e= 8.1.0\n- OpenSSL Extension\n- sodium Extension\n\n## Basic usage\n\n### Creating\n\nJust use the builder to create a new JWT/JWS tokens:\n\n```php\nuse DateTimeImmutable;\nuse Larke\\JWT\\Builder;\nuse Larke\\JWT\\Signer\\None;\nuse Larke\\JWT\\Signer\\Key\\InMemory;\n\n$now    = new DateTimeImmutable();\n$signer = new None();\n$key    = InMemory::plainText('testing')\n\n$token = (new Builder())\n    -\u003eissuedBy('http://example.com') // Configures the issuer (iss claim)\n    -\u003epermittedFor('http://example.org') // Configures the audience (aud claim)\n    -\u003eidentifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item\n    -\u003eissuedAt($now) // Configures the time that the token was issue (iat claim)\n    -\u003ecanOnlyBeUsedAfter($now-\u003emodify('+1 minute')) // Configures the time that the token can be used (nbf claim)\n    -\u003eexpiresAt($now-\u003emodify('+1 hour')) // Configures the expiration time of the token (exp claim)\n    -\u003ewithClaim('uid', 1) // Configures a new claim, called \"uid\"\n    -\u003egetToken($signer, $key); // Retrieves the generated token\n\n$token-\u003eheaders()-\u003eall(); // Retrieves the token headers\n$token-\u003eclaims()-\u003eall(); // Retrieves the token claims\n\necho $token-\u003eheaders()-\u003eget('jti'); // will print \"4f1g23a12aa\"\necho $token-\u003eclaims()-\u003eget('iss'); // will print \"http://example.com\"\necho $token-\u003eclaims()-\u003eget('uid'); // will print \"1\"\necho $token-\u003etoString(); // The string representation of the object is a JWT string (pretty easy, right?)\n```\n\n### Parsing from strings\n\nUse the parser to create a new token from a JWT string (using the previous token as example):\n\n```php\nuse Larke\\JWT\\Parser;\n\n$token = (new Parser())-\u003eparse((string) $token); // Parses from a string\n$token-\u003eheaders()-\u003eall(); // Retrieves the token headers\n$token-\u003eclaims()-\u003eall(); // Retrieves the token claims\n\necho $token-\u003eheaders()-\u003eget('jti'); // will print \"4f1g23a12aa\"\necho $token-\u003eclaims()-\u003eget('iss'); // will print \"http://example.com\"\necho $token-\u003eclaims()-\u003eget('uid'); // will print \"1\"\n```\n\n### Validating\n\nWe can easily validate if the token is valid (using the previous token and time as example):\n\n```php\nuse DateTimeImmutable;\nuse Larke\\JWT\\Validator;\nuse Larke\\JWT\\ValidationData;\n\n$now = new DateTimeImmutable();\n\n$data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp)\n$data-\u003eissuedBy('http://example.com');\n$data-\u003epermittedFor('http://example.org');\n$data-\u003eidentifiedBy('4f1g23a12aa');\n\n$validation = new Validator();\n\nvar_dump($validation-\u003evalidate($token, $data)); // false, because token cannot be used before now() + 60\n\n$data-\u003ecurrentTime($now-\u003emodify('+61 seconds')); // changing the validation time to future\n\nvar_dump($validation-\u003evalidate($token, $data)); // true, because current time is between \"nbf\" and \"exp\" claims\n\n$data-\u003ecurrentTime($now-\u003emodify('+4000 seconds')); // changing the validation time to future\n\nvar_dump($validation-\u003evalidate($token, $data)); // false, because token is expired since current time is greater than exp\n\n// We can also use the $leeway parameter to deal with clock skew (see notes below)\n// If token's claimed now is invalid but the difference between that and the validation time is less than $leeway, \n// then token is still considered valid\n$dataWithLeeway = new ValidationData($now, 20); \n$dataWithLeeway-\u003eissuedBy('http://example.com');\n$dataWithLeeway-\u003epermittedFor('http://example.org');\n$dataWithLeeway-\u003eidentifiedBy('4f1g23a12aa');\n\nvar_dump($validation-\u003evalidate($token, $dataWithLeeway)); // false, because token can't be used before now() + 60, not within leeway\n\n$dataWithLeeway-\u003ecurrentTime($now-\u003emodify('+51 seconds')); // changing the validation time to future\n\nvar_dump($validation-\u003evalidate($token, $dataWithLeeway)); // true, because current time plus leeway is between \"nbf\" and \"exp\" claims\n\n$dataWithLeeway-\u003ecurrentTime($now-\u003emodify('+3610 seconds')); // changing the validation time to future but within leeway\n\nvar_dump($validation-\u003evalidate($token, $dataWithLeeway)); // true, because current time - 20 seconds leeway is less than exp\n\n$dataWithLeeway-\u003ecurrentTime($now-\u003emodify('+4000 seconds')); // changing the validation time to future outside of leeway\n\nvar_dump($validation-\u003evalidate($token, $dataWithLeeway)); // false, because token is expired since current time is greater than exp\n```\n\n#### Important\n\n- You have to configure ```ValidationData``` informing all claims you want to validate the token.\n- If ```ValidationData``` contains claims that are not being used in token or token has claims that are not\nconfigured in ```ValidationData``` they will be ignored by ```Token::validate()```.\n- ```exp```, ```nbf``` and ```iat``` claims are configured by default in ```ValidationData::__construct()```\nwith the current time (```DateTimeImmutable```).\n- The optional ```$leeway``` parameter of ```ValidationData``` will cause us to use that number of seconds of leeway \nwhen validating the time-based claims, pretending we are further in the future for the \"Issued At\" (```iat```) and \"Not \nBefore\" (```nbf```) claims and pretending we are further in the past for the \"Expiration Time\" (```exp```) claim. This\nallows for situations where the clock of the issuing server has a different time than the clock of the verifying server, \nas mentioned in [section 4.1 of RFC 7519](https://tools.ietf.org/html/rfc7519#section-4.1).\n\n## Token signature\n\nWe can use signatures to be able to verify if the token was not modified after its generation. This library implements `Hmac`, `RSA`, `ECDSA`, `EdDSA` and `Blake2b` signatures (using 256, 384 and 512). The `none` is not signatures.\n\n### Important\n\nDo not allow the string sent to the Parser to dictate which signature algorithm\nto use, or else your application will be vulnerable to a [critical JWT security vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries).\n\nThe examples below are safe because the choice in `Signer` is hard-coded and\ncannot be influenced by malicious users.\n\n### Hmac and Blake2b\n\nHmac signatures are really simple to be used:\n\n```php\nuse DateTimeImmutable;\nuse Larke\\JWT\\Builder;\nuse Larke\\JWT\\Validator;\nuse Larke\\JWT\\Signer\\Hmac\\Sha256;\nuse Larke\\JWT\\Signer\\Key\\InMemory;\n\n$now    = new DateTimeImmutable();\n$signer = new Sha256();\n$key    = InMemory::plainText('testing');\n\n$token = (new Builder())\n    -\u003eissuedBy('http://example.com') // Configures the issuer (iss claim)\n    -\u003epermittedFor('http://example.org') // Configures the audience (aud claim)\n    -\u003eidentifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item\n    -\u003eissuedAt($now) // Configures the time that the token was issue (iat claim)\n    -\u003ecanOnlyBeUsedAfter($now-\u003emodify('+1 minute')) // Configures the time that the token can be used (nbf claim)\n    -\u003eexpiresAt($now-\u003emodify('+1 hour')) // Configures the expiration time of the token (exp claim)\n    -\u003ewithClaim('uid', 1) // Configures a new claim, called \"uid\"\n    -\u003egetToken($signer, $key); // Retrieves the generated token\n\n$key1 = InMemory::plainText('testing 1');\n$key2 = InMemory::plainText('testing');\n\n$validation = new Validator();\n\nvar_dump($validation-\u003everify($token, $signer, $key1)); // false, because the key is different\nvar_dump($validation-\u003everify($token, $signer, $key2)); // true, because the key is the same\n```\n\n### RSA, ECDSA and EdDSA\n\nRSA, ECDSA and EdDSA signatures are based on public and private keys so you have to generate using the private key and verify using the public key:\n\n```php\nuse DateTimeImmutable;\nuse Larke\\JWT\\Builder;\nuse Larke\\JWT\\Validator;\nuse Larke\\JWT\\Signer\\Key\\LocalFileReference;\nuse Larke\\JWT\\Signer\\Rsa\\Sha256; // you can use Larke\\JWT\\Signer\\Ecdsa\\Sha256 if you're using ECDSA keys\n\n$now        = new DateTimeImmutable();\n$signer     = new Sha256();\n$privateKey = LocalFileReference::file('file://{path to your private key}');\n\n$token = (new Builder())\n    -\u003eissuedBy('http://example.com') // Configures the issuer (iss claim)\n    -\u003epermittedFor('http://example.org') // Configures the audience (aud claim)\n    -\u003eidentifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item\n    -\u003eissuedAt($now) // Configures the time that the token was issue (iat claim)\n    -\u003ecanOnlyBeUsedAfter($now-\u003emodify('+1 minute')) // Configures the time that the token can be used (nbf claim)\n    -\u003eexpiresAt($now-\u003emodify('+1 hour')) // Configures the expiration time of the token (exp claim)\n    -\u003ewithClaim('uid', 1) // Configures a new claim, called \"uid\"\n    -\u003egetToken($signer, $privateKey); // Retrieves the generated token\n\n$publicKey = LocalFileReference::file('file://{path to your public key}');\n\n$validation = new Validator();\n\nvar_dump($validation-\u003everify($token, $signer, $publicKey)); // true when the public key was generated by the private one =)\n```\n\n**It's important to say that if you're using RSA keys you shouldn't invoke ECDSA signers (and vice-versa), otherwise ```sign()``` and ```verify()``` will raise an exception!**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeatil%2Flarke-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeatil%2Flarke-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeatil%2Flarke-jwt/lists"}