JSON Web Token

There are basically two different ways of implementing server side authentication for apps with a front end and an API:

Session Based System

In session based system like social networking system, e-commerce system or net banking system, the user data are stored on server side in a text file in temporary directory when user logged into the system which is called session data. The server generates the unique session ID for each user’s session data and send back to the user.

User can store that Session ID in cookies so that it can be used for further communications. When user requests for particular data after login, user has to send the session ID with each request from the cookie, so server can authenticate the user. And according to that session ID, server gives response to that user.

Session based system is STATEful as the server has to store the session for each user at server side and also user has to store session id in cookies. So if there are number of users then it is very difficult to maintain scalability and performance of the system and it will use extensive memory.

To overcome this scenario, token based system comes into the pictures.

Token Based System

Token based system is stateless, means no user data are stored on the server side, only user has to store token at client side which improves the performance and scalability of the system. When user sends the subsequent request after login, user has to provide token to the server. And from the token, server identify the user and give response to user.

Benefits of using a token-based approach

  • Cross-domain / CORS: cookies + CORS don’t play well across different domains. A token-based approach allows you to make AJAX calls to any server, on any domain because you use an HTTP header to transmit the user information.
  • Stateless (Server side scalability):there is no need to keep a session store, the token is a self-contained entity that conveys all the user information. The rest of the state lives in cookies or local storage on the client side.
  • CDN:you can serve all the assets of your app from a CDN (e.g. JavaScript, HTML, images, etc.), and your server side is just the API.
  • Decoupling:you are not tied to a particular authentication scheme. The token might be generated anywhere, hence your API can be called from anywhere with a single way of authenticating those calls.
  • Mobile ready:when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a secure API (you have to deal with cookie containers). Adopting a token-based approach simplifies this a lot.
  • CSRF:since you are not relying on cookies, you don’t need to protect against cross site requests.

JSON Web Token structure

JSON Web Tokens consist of three parts separated by dots (.), which are:

  • Header
  • Payload
  • Signature

1. Header

The header consists of two parts:
1) Type of the token, which is JWT
2) Type of cryptographic algorithm such as HMAC, HS256, SHA256 or RSA.

For example:

{
"typ": "JWT"
"alg": "HS256",
}

2. Payload

The second part of the token is the payload, which contains the claims. Claims are statements about an user and additional metadata.

For example:

{
"user_phone": " 9999999999",
"user_name": "ABC XYZ",
"admin": true
}

3. Signature

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

For example:

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

The signature is used to verify that the sender of the JWT and to ensure that the message wasn’t changed in the way.

Putting all together

The output is three Base64 strings separated by dots that can be easily passed in HTML and HTTP environments. The following shows a JWT that has the previous header and payload encoded, and it is signed with a secret.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3Bob25lIjoiOTk5OTk5OTk5OSIsInVzZXJfbmFtZSI6IkFCQyBYWVoiLCJhZG1pbiI6dHJ1ZX0.19mplFcB04qRr7oBz7r6xWWiJyhqHY4F-UGBct4LpXU

How JWT works?

  1. A client sends a request to the authentication server containing login information.
  2. The authentication server generates a new JWT access token and returns it to the client.
  3. On every request, the client sends the token in authorization header.
  4. The server then validates the token and, if it’s valid, returns the secure resource to the client.
Fig 1. JWT Workflow
Fig 1. JWT Workflow

JWT implementation in php

1. To install JWT, run the command in cmd

Composer require firebase/php-jwt

2. Create token

use Firebase\JWT\JWT;
$user_name = $_POST[‘user_name’];
$password = $_POST[‘password’];
$key = “secret_key”;
$payload = array(
           “iss” => “http://sample.org”,
           “aud” => “http://sample.com”,
           “iat” => 1356999524,
           “nbf” => 1357000000,
           “user_name” => $user_name,
           “password” => $password
           );
$jwt = JWT::encode($payload, $key);
echo $jwt;

3. Get data from the token

use Firebase\JWT\JWT;
$user_data = JWT::decode($jwt, $key, array(‘HS256’)); var_dump($user_data);

Implement JWT in laravel

1. To install JWT, you will need

Laravel 4 or 5
PHP 5.4

2. Edit your composer.json to require the package.

“require”:{
     “tymon.jwt-auth”:”0.5.*”
}

3. Then run composer update in your terminal to pull it in.

composer update

4. Once this has finished, you will need to add the service provider to the providers array in your app.php config as follows:

Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,

5. Next, also in the app.php config file, under the aliases array, you may want to add the JWTAuth facade.

‘JWTAuth’ => Tymon\JWTAuth\Facades\JWTAuth::class,

6. Also included is a Facade for the PayloadFactory. This gives you finer control over the payloads you create if you require it

‘JWTFactory’ => Tymon\JWTAuth\Facades\JWTFactory::class,

7. Publish the config using the following command:

php artisan vendor:publish --provider=”Tymon\JWTAuth\Providers\JWTAuthServiceProvider”

8. Don’t forget to set a secret key in the config file

A helper command to generate a key as follows:

php artisan jwt:generate

9. Now create token (based on user credentials),

use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;

class AuthenticateController extends Controller
{
     public function authenticate(Request $request)
     {
          // grab credentials from the request
          $creadentials = $request->only(‘email’,’password’);
          try{
               // attempt to verify the credentials and create token
               If(! $token = JWTAuth::attempt($creadentials)){
                    return response()->json([‘error’ => ‘invalid credentials’],401);
               }
          }catch(JWTException $e){
          return response()->json([‘error’ => ‘could not create token’],500);
     }
     // all good so return the token
     return response()->json(compact(‘token’));
     }
}

10 .Create token (based on anything you like)

use JWTFactory;

$customClaims = [‘user_phone’=>’9999999999’];
$payload = JWTFactory::make($customClaims);
$token = JWTAuth::encode($payload);

References:

  1. https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
  2. https://auth0.com/learn/json-web-tokens/
  3. https://jwt.io/
  4. https://www.sitepoint.com/php-authorization-jwt-json-web-tokens/

Leave a Comment