<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MV Associati Tech Gems &#187; expressive</title>
	<atom:link href="http://www.mvassociati.it/en/gems/topic/expressive/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mvassociati.it/en/gems</link>
	<description>Technical Article from MV Associati experience</description>
	<lastBuildDate>Fri, 04 Aug 2017 10:31:17 +0000</lastBuildDate>
	<language>en-EN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Token based authentication in Zend Expressive</title>
		<link>http://www.mvassociati.it/en/gems/software-development/token-based-authentication-with-zend-expressive/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=token-based-authentication-with-zend-expressive</link>
		<comments>http://www.mvassociati.it/en/gems/software-development/token-based-authentication-with-zend-expressive/#comments</comments>
		<pubDate>Wed, 01 Mar 2017 15:36:42 +0000</pubDate>
		<dc:creator>drigani</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[expressive]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[routes]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://www.mvassociati.it/en/gems/?p=694</guid>
		<description><![CDATA[Authentication is one of the most important parts of any web application. As RESTful API designers we often deal with the need of authenticating our users in order to handle and display sensible information. In this post, we&#8217;ll focus in a specific authentication strategy called token based authentication using Zend Expressive micro framework. First of [...]]]></description>
			<content:encoded><![CDATA[<p>Authentication is one of the most important parts of any web application. As RESTful API designers we often deal with the need of authenticating our users in order to handle and display sensible information. In this post, we&#8217;ll focus in a specific authentication strategy called token based authentication using Zend Expressive micro framework.<span id="more-694"></span></p>
<p>First of all, if you still don&#8217;t know anything about Zend Expressive check it out:<a href=" https://zendframework.familiar.io/zend-expressive/" target="_blank"> http://zendframework.github.io/zend-expressive/</a></p>
<p>Prerequisites:</p>
<ul>
<li>A decent grasp of PHP</li>
<li>REST fundamentals</li>
<li>Basic Zend Expressive knowledge</li>
</ul>
<p>“Token based authentication works by ensuring that each request to a server is accompanied by a signed token which the server verifies for authenticity and only then responds to the request.”</p>
<p>So, we assume that we have a login page that will send the user credentials to our API endpoint (that will be http://api.mvlabs.it/api/v1/user/login in our example) and, if the given credentials are correct, then the API will respond with a token to the Front-End and the Front-End application will use the token to access the restricted resources in the following requests.</p>
<p></p>
<h2>OK, so &#8230;how can I do that with Zend Expressive?</h2>
<p>In <strong>Zend Expressive</strong> we could use a Middleware plugged into our pipeline to verify the token validity. So, for this scope we’ll use the <a href="https://familiar.com/tuupola/slim-jwt-auth" target="_blank"><strong>tuupola/slim-jwt-auth</strong></a> middleware. It was originally developed for Slim but can be used with any framework that complies with the PSR-7 standard and of course, Zend Expressive is one of them! Yep, code reuse is a great thing enabled by Middleware! Ok, let’s take a look. First of all, we need to add to our <strong>Zend Expressive skeleton</strong> application the jwt auth middleware:</p><pre class="crayon-plain-tag">$ composer require tuupola/slim-jwt-auth</pre><p>Now we need to add some configurations parameters that will be used by the <strong>JwtAuthentication Middleware</strong>. In fact, the only mandatory parameter is <strong>&#8220;secret&#8221;</strong> which is used to verify the token signature, only the issuer application has to know it and should never be disclosed in any way. So:</p>
<p>config/autoload/jwt-authentication.global.php</p><pre class="crayon-plain-tag">return [
   'jwt-authentication' =&amp;gt; [
       &quot;secret&quot; =&amp;gt; getenv(&quot;JWT_SECRET&quot;),
       &quot;path&quot; =&amp;gt; [&quot;/&quot;],
       &quot;passthrough&quot; =&amp;gt; [&quot;/api/v1/user/login&quot;, &quot;/api/v1/ping&quot;],
       &quot;error&quot; =&amp;gt; function ($request, $response, &amp;amp;$arguments) {
           $data[&quot;status&quot;] = &quot;error&quot;;
           $data[&quot;message&quot;] = $arguments[&quot;message&quot;];

           return $response
               -&amp;gt;withHeader(&quot;Content-Type&quot;, &quot;application/json&quot;)
               -&amp;gt;write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
       }
   ]
];</pre><p>Some notes about the configuration above:</p>
<ul>
<li>The optional <strong>path</strong> parameter allows us to specify the protected part of your website.</li>
<li>With optional <strong>passthrough</strong> parameter we can make exceptions to <strong>path</strong> parameter.</li>
<li><strong>error</strong> is called when authentication fails. It receives last error message as argument.</li>
</ul>
<p>Now we can create our <strong>JwtAuthentication Middleware</strong> through a factory with our configuration defined above.</p>
<p>src/App/Factory/JwtAuthenticationFactory.php</p><pre class="crayon-plain-tag">namespace App\Factory;

use Interop\Container\ContainerInterface;
use Slim\Middleware\JwtAuthentication;

class JwtAuthenticationFactory
{
   public function __invoke(ContainerInterface $container)
   {
       $config = $container-&amp;gt;get('config');
       return new JwtAuthentication($config['jwt-authentication']);
   }
}</pre><p>Now is time to add the <strong>Jwt Authentication Middleware</strong> to the <strong>ZE middleware pipeline</strong>, then it will have the responsibility to determine if a token is valid for the protected endpoints.</p>
<p>config/autoload/middleware-pipeline.global.php</p><pre class="crayon-plain-tag">return [
   'dependencies' =&amp;gt; [
       'factories' =&amp;gt; [
	...
           Slim\Middleware\JwtAuthentication::class =&amp;gt; App\Factory\JwtAuthenticationFactory::class,
	...
       ],
   ],
   'middleware_pipeline' =&amp;gt; [
       'always' =&amp;gt; [
           'middleware' =&amp;gt; [
	       ...
               Slim\Middleware\JwtAuthentication::class,
               ...
           ],
           'priority' =&amp;gt; 10000,
    ],
    'routing' =&amp;gt; [
       'middleware' =&amp;gt; [
            ...
       ],
       'priority' =&amp;gt; 1,
    ],
       ...
   ],
];</pre><p>At this point we need to define some routes in our configuration file, so let&#8217;s add the following:</p>
<ul>
<li>/api/v1/ping unprotected example endpoint</li>
<li>/api/v1/user/login (unprotected) used for authentication and token generation</li>
<li>/api/v1/user/:id the protected endpoint example that returns user specific data</li>
</ul>
<p>config/autoload/routes.global.php</p><pre class="crayon-plain-tag">return [
   'dependencies' =&amp;gt; [
       'factories' =&amp;gt; [
           App\Action\AuthAction::class =&amp;gt; App\Action\AuthFactory::class,
       ],
   ],

   'routes' =&amp;gt; [
       [
           'name' =&amp;gt; 'api.ping',
           'path' =&amp;gt; '/api/v1/ping',
           'middleware' =&amp;gt; App\Action\PingAction::class,
           'allowed_methods' =&amp;gt; ['GET'],
       ],
       [
           'name' =&amp;gt; 'api.auth',
           'path' =&amp;gt; '/api/v1/user/login',
           'middleware' =&amp;gt; App\Action\AuthAction::class,
           'allowed_methods' =&amp;gt; ['POST'],
       ],
       [
           'name' =&amp;gt; 'api.user.get',
           'path' =&amp;gt; '/api/v1/user/:id',
           'middleware' =&amp;gt; App\Action\UsersAction::class,
           'allowed_methods' =&amp;gt; ['GET'],
       ],
   ],
];</pre><p>Now, we need to add the logic that will handles the data sent by the login form, validate it against a database, and after determining that the credentials are valid, will generate the token. So, we&#8217;ll define the <strong>AuthAction Middleware</strong> that will have those responsibilities:</p><pre class="crayon-plain-tag">namespace App\Action;
namespace App\Action;

use App\Entity\User;
use App\Service\UserService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse;

class AuthAction
{
    private $userService;

    public function __construct(UserService $userService)
    {
        $this-&amp;gt;userService = $userService;
    }

    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
    {
        $post = $request-&amp;gt;getParsedBody();
        $username = $post['username'];
        $password = $post['password'];

        $user = $this-&amp;gt;userService-&amp;gt;getUserByEmailPassword($username, $password);
        if ($user instanceof User) {
            $jwt = $this-&amp;gt;userService-&amp;gt;getAuthTokenForUser($user);

            return new JsonResponse([
                'time' =&amp;gt; time(),
                'jwt' =&amp;gt; $jwt,
            ]);
        }

        return new JsonResponse(['status' =&amp;gt; 'error'], 401);
    }
}</pre><p>Let&#8217;s take a detailed look to the token generation in the UserService:</p><pre class="crayon-plain-tag">namespace App\Service;

use App\Entity\User;
use Firebase\JWT\JWT;

class UserService
{

    ...

    public function geAuthTokenForUser(User $user)
    {
        $now = new \DateTime();
        $future = new \DateTime(&quot;now +2 hours&quot;);

        $random_number = openssl_random_pseudo_bytes(32); //generate using openssl_random_pseudo_bytes
        $jti = hash('sha256', $user-&amp;gt;getId() . $random_number);
        $serverName =  $this-&amp;gt;config['api']['endpoint'];
        /*
         * Create the token as an array
         */
        $data = [
            &quot;iat&quot; =&amp;gt; $now-&amp;gt;getTimeStamp(),  // Issued at: time when the token was generated
            'jti' =&amp;gt; $jti, // Json Token Id: an unique identifier for the token
            'iss' =&amp;gt; $serverName, // Issuer
            'nbf' =&amp;gt; $now-&amp;gt;getTimeStamp()+10, // Not before
            &quot;exp&quot; =&amp;gt; $future-&amp;gt;getTimeStamp(), // Expire
            'data' =&amp;gt; [ // Data related to the signer user
                'userId' =&amp;gt; $user-&amp;gt;getId(), // userid from the users table
                'username' =&amp;gt; $user-&amp;gt;getUsername(), // User name
            ]
        ];

        /*
         * Encode the array to a JWT string. Second parameter is the key to encode the token.             *
         * The output token $jwt can be validated at http://jwt.io/
         */
        $jwt = JWT::encode(
            $data,
            $this-&amp;gt;config['jwt-authentication']['secret'],
            &quot;HS512&quot;
        );

        return $jwt;
    }
}</pre><p>In order to check that everything is OK, let&#8217;s do a test call to our authentication endpoint with postman, passing our authentication credentials.</p>
<p></p>
<p>Good, everything looks fine, so, at this point the client will have the token, and can store it using a storage mechanism like HTML5 Web Storage.</p>
<p>Now let’s retrieve a resource that is protected by our JWT mechanism. But first we need to set the Authorization header with the contents of the JWT in the format of Bearer [JWT]</p>
<p></p>
<p>As we can see in the image above, we can access to the restricted resource once that we passed our authentication token.</p>
<h2>Summary</h2>
<p>This is a very reliable method to secure your information. From here on, you can try to implement a token based authentication using ZE in your next API. Feel free to share your constructive feedback or ask a question. Drop a note below, we&#8217;ll be happy to receive your comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mvassociati.it/en/gems/software-development/token-based-authentication-with-zend-expressive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
