eljam / guzzle-jwt-middleware
A jwt authentication middleware for guzzle 6
Installs: 560 186
Dependents: 4
Suggesters: 0
Security: 0
Stars: 29
Watchers: 1
Forks: 13
Open Issues: 0
Requires
- php: >=7.4.0
- guzzlehttp/guzzle: ^7.0
- psr/simple-cache: ^1 || ^2 || ^3
- symfony/options-resolver: >=2.8
- symfony/property-access: >=2.8
Requires (Dev)
- kodus/mock-cache: ^1.0
- php-coveralls/php-coveralls: ^2.4
- phpunit/phpunit: ^9.5
README
Introduction
Works great with LexikJWTAuthenticationBundle
Installation
composer require eljam/guzzle-jwt-middleware
Usage
<?php use Eljam\GuzzleJwt\JwtMiddleware; use Eljam\GuzzleJwt\Manager\JwtManager; use Eljam\GuzzleJwt\Strategy\Auth\QueryAuthStrategy; use GuzzleHttp\Client; use GuzzleHttp\HandlerStack; require_once 'vendor/autoload.php'; //Create your auth strategy $authStrategy = new QueryAuthStrategy(['username' => 'admin', 'password' => 'admin']); //Optionnal: create your persistence strategy $persistenceStrategy = null; $baseUri = 'http://api.example.org/'; // Create authClient $authClient = new Client(['base_uri' => $baseUri]); //Create the JwtManager $jwtManager = new JwtManager( $authClient, $authStrategy, $persistenceStrategy, [ 'token_url' => '/api/token', ] ); // Create a HandlerStack $stack = HandlerStack::create(); // Add middleware $stack->push(new JwtMiddleware($jwtManager)); $client = new Client(['handler' => $stack, 'base_uri' => $baseUri]); try { $response = $client->get('/api/ping'); echo($response->getBody()); } catch (TransferException $e) { echo $e->getMessage(); } //response //{"data":"pong"}
Auth Strategies
QueryAuthStrategy
$authStrategy = new QueryAuthStrategy( [ 'username' => 'admin', 'password' => 'admin', 'query_fields' => ['username', 'password'], ] );
FormAuthStrategy
$authStrategy = new FormAuthStrategy( [ 'username' => 'admin', 'password' => 'admin', 'form_fields' => ['username', 'password'], ] );
HttpBasicAuthStrategy
$authStrategy = new HttpBasicAuthStrategy( [ 'username' => 'admin', 'password' => 'password', ] );
JsonAuthStrategy
$authStrategy = new JsonAuthStrategy( [ 'username' => 'admin', 'password' => 'admin', 'json_fields' => ['username', 'password'], ] );
Persistence
To avoid requesting a token everytime php runs, you can pass to JwtManager
an implementation of TokenPersistenceInterface
.
By default NullTokenPersistence
will be used.
Simpe cache adapter (PSR-16)
If you have any PSR-16 compatible cache, you can use it as a persistence handler:
<?php use Eljam\GuzzleJwt\Persistence\SimpleCacheTokenPersistence; use Psr\SimpleCache\CacheInterface; /** * @var CacheInterface */ $psr16cache; $persistenceStrategy = new SimpleCacheTokenPersistence($psr16cache);
Optionnally you can specify the TTL and cache key used:
<?php use Eljam\GuzzleJwt\Persistence\SimpleCacheTokenPersistence; use Psr\SimpleCache\CacheInterface; /** * @var CacheInterface */ $psr16cache; $ttl = 1800; $cacheKey = 'myUniqueKey'; $persistenceStrategy = new SimpleCacheTokenPersistence($psr16cache, $ttl, $cacheKey);
Custom persistence
You may create you own persistence handler by implementing the TokenPersistenceInterface
:
namespace App\Jwt\Persistence; use Eljam\GuzzleJwt\Persistence\TokenPersistenceInterface; class MyCustomPersistence implements TokenPersistenceInterface { /** * Save the token data. * * @param JwtToken $token */ public function saveToken(JwtToken $token) { // Use APCu, Redis or whatever fits your needs. return; } /** * Retrieve the token from storage and return it. * Return null if nothing is stored. * * @return JwtToken Restored token */ public function restoreToken() { return null; } /** * Delete the saved token data. */ public function deleteToken() { return; } /** * Returns true if a token exists (although it may not be valid) * * @return bool */ public function hasToken() { return false; } }
Token key
Property accessor
With the property accessor you can point to a node in your json.
Json Example:
{ "status": "success", "message": "Login successful", "payload": { "token": "1453720507" }, "expires_in": 3600 }
Library configuration:
$jwtManager = new JwtManager( $authClient, $authStrategy, $persistenceStrategy, [ 'token_url' => '/api/token', 'token_key' => 'payload.token', 'expire_key' => 'expires_in' ] );
Default behavior
By default this library assumes your json response has a key token
, something like this:
{ token: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9..." }
but now you can change the token_key in the JwtManager options:
$jwtManager = new JwtManager( $authClient, $authStrategy, $persistenceStrategy, [ 'token_url' => '/api/token', 'token_key' => 'access_token', ] );
Authorization Header Type
Some endpoints use different Authorization header types (Bearer, JWT, etc...).
The default is Bearer, but another type can be supplied in the middleware:
$stack->push(new JwtMiddleware($jwtManager, 'JWT'));
Cached token
To avoid too many calls between multiple request, there is a cache system.
Json example:
{ token: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9...", expires_in: "3600" }
$jwtManager = new JwtManager( $authClient, $authStrategy, $persistenceStrategy, [ 'token_url' => '/api/token', 'token_key' => 'access_token', 'expire_key' => 'expires_in', # default is expires_in if not set ] );
The bundle natively supports the exp field in the JWT payload.