Slim4 API Tutorial: 3 JWT access token

Slim4 Login API and JWT access token

In Slim4 API Tutorial 3 JWT access token , we will discuss how to use Slim4 JWT access token in login API. After user successfully register, application / systems need a method to secure the data from unauthorized access. Login is one of the authentication methods to secure the data that belongs to the user. Usually login requires username and password . On web/frontend or mobile apps, user enter their username and password in a form view. At backend, username and password are sent by request. It can be formated in json. Furthermore, system will authenticate it, if username and password are correct then a response will be sent. One method that use to exchange the data between backend and frontend or mobile apps is JSON Web Token (JWT).

PHP Slim4 JWT Access Token

One of JWT access token packages can be used in Slim4 is firebase/php-jwt. This package supports function to encode and decode access token. The access token itself can be containing data such as created time, expired time, and user information. Install firebase/php-jwt by using composer:

composer require firebase/php-jwt

JWT key and algorithm settings

To make firebase/php-jwt encode and decode function properly, we need to set secret key and algorithm. This setting proposed to make encryption data same as decoded data (plaintext). Add secret key and algorithm in config/settings.php

// other code
'jwt' => [
    'key' => 'secretkey',
    'alg' => 'HS256',
]
// other code

PHP login authentication using JWT access token

At the API login, before system responds using JWT access token, we need to validate the user's request and existance of the user. Validation process checks the email and password is valid or not. If the validation is valid, then system / application will check user's existance. It will check on user data in the database. If user exists on the database, system will generate JWT access token. Created time, expired time, user ID, user email will be stored in the JWT access token.

// other code
use Firebase\JWT\JWT;
// other code
$app->post('/login', function (Request $request, Response $response) use ($settings) {
    $body = $request->getBody();
    $json = json_decode($body, true);
    $validator = new Validator;
    $validator->requirePresence('email', true, 'Email field is required')
        ->notEmptyString('email', 'Email is required')
        ->email('email', false, 'Email must be valid')
        ->requirePresence('password', true, 'Password field is required')
        ->notEmptyString('password', 'Password is required');
    $errors = $validator->validate($json);
    if ($errors) {
        $messages['message'] = 'Login failed';
        foreach($errors as $error) {
            $messages['error'][] = array_values($error);
        }
        $statusCode = 401;
    } else {
        $user = User::where('email', $json['email'])
            ->where('password', sha1($json['password']))
            ->where('status', 1)
            ->first();
        if ($user) {
            $iat = new DateTimeImmutable(); // issued at time
            $exp = $iat->modify('+30 minutes')->getTimestamp(); // expired
            $nbf = $iat->getTimestamp(); // not before
            $payload = [
                'iat' => $iat->getTimestamp(),
                'exp' => $exp,
                'nbf' => $nbf,
                'user_id' => $user->id,
                'email' => $user->email,
            ];
            $message['access_token'] = JWT::encode($payload, $settings['jwt']['key'], $settings['jwt']['alg']);
            $statusCode = 200;
        } else {
            $message['message'] = 'Login failed';
            $statusCode = 401;
        }
    }
    $data = json_encode($message);
    $response->getBody()->write($data);
    return $response
            ->withHeader('Content-Type', 'application-json')
            ->withStatus($statusCode);
});
// other code

Login API using Postman:

Slim4 login JWT access token using Postman

Decode JWT Aaccess token

Sometimes the system requires additional data to be able to continue next process, for example user_id will use to find out user last update or maybe it will use as tag in shopping cart. One of effective way to get that data is decode function (decode). To be able to generate valid data, secret key and the algorithm for encryption must be same as decryption. Example code for decode function is as follows:

use Firebase\JWT\Key;

...
$app->post('/decode', function (Request $request, Response $response) use ($settings) {
    $body = $request->getBody();
    $json = json_decode($body, true);
    $key = new Key($settings['jwt']['key'], $settings['jwt']['alg']);
    $decode = JWT::decode($json['access_token'], $key);
    $response->getBody()->write(json_encode($decode));
    return $response->withHeader('Content-Type', 'application-json');
});
...

Decode JWT access token using Postman:

Slim4 decode JWT access token

Full code can be viewed at Github.

3 thoughts on “Slim4 Tutorial API: 3 JWT access token

  1. Pingback: Slim4 Fashion Store API: 4 Autentikasi dan middleware – PerangkatLunakKu

  2. Pingback: Slim4 Tutorial API: 4 Middleware autentikasi - PerangkatLunakKu

  3. Pingback: Tutorial PHP Backend Slim4 - PerangkatLunakKu

Leave a Reply