soluble/wallit

0.5.1 2018-10-26 15:01 UTC

This package is auto-updated.

Last update: 2024-03-27 02:25:50 UTC


README

PHP Version Build Status codecov Scrutinizer Code Quality Latest Stable Version Total Downloads License

PSR-15 Middleware for dealing with JWT generation and checks.

Status: Experimental. Not yet used in production, if interested take a look at the issues and feel welcome to make suggestions or open P/R :)

Requirements

  • PHP 7.1

Recommended

For zend-expressive 2.0 use the 0.3 release.

Install

$ composer require soluble-wallit

Configure

Copy soluble-wallit.config.php.dist in your autoload directory.

cp ./vendor/soluble/wallit/config/soluble-wallit.config.php.dist ./config/autoload/soluble-wallit.config.local.php

Edit the config file and add your token keys

Register (zend-expressive 3.0)

Ensure Soluble\Wallit\Config\ConfigProvider::class is registered in the ./config/config.php file.

<?php
use Zend\ConfigAggregator\ArrayProvider;
use Zend\ConfigAggregator\ConfigAggregator;
use Zend\ConfigAggregator\PhpFileProvider;

$cacheConfig = [
    'config_cache_path' => 'data/config-cache.php',
];

$aggregator = new ConfigAggregator([
    new ArrayProvider($cacheConfig),
    
    // Register the Soluble Wallit ConfigProvider    
    Soluble\Wallit\Config\ConfigProvider::class,
    
    new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
    new PhpFileProvider('config/development.config.php'),
], $cacheConfig['config_cache_path']);

return $aggregator->getMergedConfig();

Usage (zend-expressive 3.0)

To quickly browse the examples, see the smoke tests directory.

Example 1

Create a PSR-15 handler to generate a JWT token upon successful authentication:

<?php declare(strict_types=1);

namespace App\Handler;

use Psr\Http\Message\{ResponseInterface, ServerRequestInterface};
use Psr\Http\Server\RequestHandlerInterface;
use Fig\Http\Message\StatusCodeInterface;
use Ramsey\Uuid\Uuid;
use Soluble\Wallit\Service\JwtService;
use Soluble\Wallit\Token\Jwt\JwtClaims;
use Zend\Diactoros\Response\JsonResponse;

class AuthHandler implements RequestHandlerInterface
{
    /**
     * @var JwtService
     */
    protected $jwtService;

    public function __construct(JwtService $jwtService)
    {
        $this->jwtService = $jwtService;
    }

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $method = $request->getMethod();
        if ($method !== 'POST') {
            throw new \RuntimeException('TODO - Handle error your way ;)');
        }

        $body = $request->getParsedBody();
        $login = $body['login'] ?? '';
        $password = $body['password'] ?? '';

        if ($login === 'demo' && $password === 'demo') {
            $token = $this->jwtService->createToken([
                JwtClaims::ID => Uuid::uuid1(),
                'login'       => $login
            ]);

            return new JsonResponse([
                'access_token' => (string) $token,
                'token_type'   => 'example',
            ]);
        }

        return (new JsonResponse([
            'success' => false
        ]))->withStatus(StatusCodeInterface::STATUS_UNAUTHORIZED);
    }
}

Its related factory can be:

<?php declare(strict_types=1);

namespace App\Handler;

use Psr\Container\ContainerInterface;
use Soluble\Wallit\Service\JwtService;

class AuthHandlerFactory
{
    public function __invoke(ContainerInterface $container): AuthHandler
    {
        return new AuthHandler(
            $container->get(JwtService::class)
        );
    }
}

Add a route in ./config/routes.php

<?php
//....
$app->post('/auth', App\Handler\AuthHandler::class, 'auth');

Example 2: Check JWT

Simply pipe or add the JwtAuthMiddleware::class to the desired route.

As an example in the ./config/routes.php file :

<?php declare(strict_types=1);

use Soluble\Wallit\Middleware\JwtAuthMiddleware;

// ...
    $app->get('/admin', [
        JwtAuthMiddleware::class,
        App\Handler\AdminHandler::class
    ], 'admin');

Example 3: Retrive the token

The token is available as a request attribute: $request->getAttribute(JwtAuthMiddleware::class).

<?php declare(strict_types=1);
namespace App\Handler;

use Psr\Http\Message\{ResponseInterface, ServerRequestInterface};
use Psr\Http\Server\RequestHandlerInterface;
use Soluble\Wallit\Middleware\JwtAuthMiddleware;
use Zend\Diactoros\Response\HtmlResponse;
use Zend\Expressive\Template\TemplateRendererInterface;
use Lcobucci\JWT\Token;

class AdminHandler implements RequestHandlerInterface
{
    /**
     * @var TemplateRendererInterface
     */
    private $template;
    public function __construct(TemplateRendererInterface $template) {
        $this->template = $template;
    }
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $token = $this->getTokenFromRequest($request);
        return new HtmlResponse($this->template->render('pages::admin', [
            'token' => $token,
            'login' => $token->getClaim('login')
        ]));
    }    
    protected function getTokenFromRequest(ServerRequestInterface $request): Token
    {
        return $request->getAttribute(JwtAuthMiddleware::class);
    }
}

Standards