0 Shares 59794 Views

LARAVEL API- JWT Examples

LARAVEL API- Some JWT Examples

Today we will develop an API (Application Programming Interface) application via Laravel and provide security through JWT.

So what is JWT primarily? Let’s address this issue.

JWT (JSON WEB TOKEN)

JWT is a Token format standardized by the IETF organization. Detailed information about the standard can be found here. Among the JWT communication systems (eg Mobile, Web, Cloud, IoT, etc.), user identification, verification, and information security, etc. matter.

The Structure of JWT

JWT is composed of 3 separate parts encoded in Base64. These parts are ‘.’ separated by. Separated by “. These parts are:

  • Header
  • Payload
  • Signature

HEADER

This is where JWT’s cookies are located. The standard is defined as follows.

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

Alg : Where it determines the Cryptographic Algorithm for JWT. Supported Algorithms vary depending on the language you use. You can review supported Algorithms via jwt.io.

Typ : Indicates that the Header type used is JWT.

PAYLOAD

Although there are some standards here, it is the part that contains the data we want to carry in general. To mention some standard keys;

  • iss (issuer): Publisher
  • sub (subject): Subject
  • exp (expiration time): Expiration date
  • nbf (not before time): Before this Date
  • iat (issued at the time): Created on

We’ll be talking about these areas in the future, as many of the standard switches available are much more than enough.

SIGNATURE

This is the part where the Key is used to create the JWT. The header is encrypted with the specified encryption method.

~~~

Except for the signature part of the JWT you produce, the data can be read in it. Simply decode the Base64. But you cannot make any changes to the information in the content because the key will become unusable.

JWT Advantages

Since they are stateless, database operations are not required for users’ information.

  • Session management can be done without in-house cookies.
  • A single switch can operate on multiple servers.
  • Database and so on are much faster because no operations are performed.

JWT Drawbacks

  • If your secret key is not strong enough, it can be easily manipulated.
  • There is no way to override the server-side because they are stateless. (We can prevent it from working with several methods.)

In general, we talked about JWT. Now let’s examine how it works on a simple Laravel API. Generally, two different libraries are used:

  • firebase / PHP-jwt
  • Tymon / jwt-auth

We will use “tymon / jwt-auth üzerinde on our application. We are primarily involved with Composer in our project.

composer require tymon/jwt-auth:1.0.0

At Medianova, we are developing the project with Laravel 6, which will be explained in section 5.4 and above. After installing the package through Artisan CLI

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

You will then see jwt.php in app/config/ Then we proceed to the step of setting the password for JWT. Again via the terminal

php artisan jwt:secret

After that, the JWT_SECRET key will be created in your .env file. Since it is a sample application, we will describe it as if there is a database connection. There will be no difference as you can run through your model if you want, which will tell you through the User model that comes as standard. First of all, we make the following changes on /App/User.php.

use Tymon\JWTAuth\Contracts\JWTSubject;

...class User extends Authenticatable implements JWTSubject{

public function getJWTIdentifier()

{

return $this->getKey();

}

public function getJWTCustomClaims()

{

return [];

}

...

after these changes, our model file should look like this;

<?php

namespace App;

use Tymon\JWTAuth\Contracts\JWTSubject;

use Illuminate\Foundation\Auth\User as Authenticatable;

use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements JWTSubject

{

use Notifiable;

/**

* Get the identifier that will be stored in the subject claim of the JWT.

*

* @return mixed

*/

public function getJWTIdentifier()

{

return $this->getKey();

}

/**

* Return a key value array, containing any custom claims to be added to the JWT.

*

* @return array

*/

public function getJWTCustomClaims() : array

{

return [];

}

/**

* The attributes that are mass assignable.

*

* @var array

*/

protected $fillable = [

'name', 'email', 'password',

]; /**

* The attributes that should be hidden for arrays.

*

* @var array

*/

protected $hidden = [

'password', 'remember_token',

]; /**

* The attributes that should be cast to native types.

*

* @var array

*/

protected $casts = [

'email_verified_at' => 'datetime',

];

}

</code>

Now let's create a route for user input, detail, output, etc. The api.php in the router should look like this;

<code>

# router/api.php

.....Route::group([ 'middleware' => ['api'],

'prefix' => 'member'], static function ($router) {

Route::post('login', 'MemberController@login');

Route::post('register', 'MemberController@register');

Route::group(['middleware' => 'jwt.verify'], static function( $router){

Route::post('logout', 'MemberController@logout');

Route::post('refresh', 'MemberController@refresh');

Route::get('detail', 'MemberController@detail'); });

});

.....

and then create the jwt.verify middleware, so that we can control requests from routes. Artisan from CLI

php artisan make:middleware JwtMiddleware

:/app/Http/Middleware JwtMiddleware file will be formed under the contents of the following edit.

<?php

namespace App\Http\Middleware;use Closure;

use JWTAuth;

use Exception;

use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;

class JwtMiddleware extends BaseMiddleware

{

/**

* Handle an incoming request.

*

* @param \Illuminate\Http\Request $request

* @param \Closure $next

* @return mixed

*/

public function handle($request, Closure $next)

{

try {

$user = JWTAuth::parseToken()->authenticate();

if( !$user ) throw new Exception('User Not Found');

} catch (Exception $e) {

if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){

return response()->json([

'data' => null,

'status' => false,

'err_' => [

'message' => 'Token Invalid',

'code' => 1

]

]

);

}else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){

return response()->json([

'data' => null,

'status' => false,

'err_' => [

'message' => 'Token Expired',

'code' =>1

]

]

);

}

else{

if( $e->getMessage() === 'User Not Found') {

return response()->json([

"data" => null,

"status" => false,

"err_" => [

"message" => "User Not Found",

"code" => 1

]

]

); }

return response()->json([

'data' => null,

'status' => false,

'err_' => [

'message' => 'Authorization Token not found',

'code' =>1

]

]

);

}

}

return $next($request);

}

}

and to use this middleware on routes we define it on the kernel. : /app/Http/Kernel.php is now fully operational.

...

protected $routeMiddleware = [

....

'jwt.verify' => \App\Http\Middleware\JwtMiddleware::class,

...

Let’s create the controls that meet the routes. Again, Artisan can do this operation via CLI. In that

php artisan make:controller MemberController

After that, the contents of the MemberController will be created in

/app/Http/Controller.

...

use App\Http\Requests\RegisterRequest;

use Exception;

use Illuminate\Http\JsonResponse;

use Illuminate\Http\Request;

use JWTAuth;

use Hash;

use App\User;

use Tymon\JWTAuth\Exceptions\JWTException;

...protected $data = [];/**

*

* @return void

*/

public function __construct()

{

$this->data = [

'status' => false,

'code' => 401,

'data' => null,

'err' => [

'code' => 1,

'message' => 'Unauthorized'

]

];

}

/**

* With the request-> only method, we only take the email-password as a *parameter and perform the user authentication with the attempt *function of the auth method in the laravel. If the user is correct, we *return a token for the user to use for later processing.

*

* @param Request $request

* @return JsonResponse

*/

public function login(Request $request): JsonResponse

{ $credentials = $request->only(['email', 'password']);

try {

if (!$token = JWTAuth::attempt($credentials)) {

throw new Exception('invalid_credentials');

}

$this->data = [

'status' => true,

'code' => 200,

'data' => [

'_token' => $token

],

'err' => null

]; } catch (Exception $e) {

$this->data['err']['message'] = $e->getMessage();

$this->data['code'] = 401;

} catch (JWTException $e) {

$this->data['err']['message'] = 'Could not create token';

$this->data['code'] = 500;

}

return response()->json($this->data, $this->data['code']);

}/**

*I do not elaborate as the user registers method used here before, as described in RegisterRequest.

* @param RegisterRequest $request

* @return JsonResponse

*/

public function register(RegisterRequest $request): JsonResponse

{

$user = User::create([

'name' => $request->post('name'),

'email' => $request->post('email'),

'password' => Hash::make($request->post('password'))

]);

$this->data = [

'status' => true,

'code' => 200,

'data' => [

'User' => $user

],

'err' => null

];

return response()->json($this->data, $this->data['code']);

}/**

* Bring the details of the verified user.

*

* @return JsonResponse

*/

public function detail(): JsonResponse

{

$this->data = [

'status' => true,

'code' => 200,

'data' => [

'User' => auth()->user()

],

'err' => null

];

return response()->json($this->data);

}/**

*Log out the user and make the token unusable.

* @return JsonResponse

*/

public function logout(): JsonResponse

{

auth()->logout();

$data = [

'status' => true,

'code' => 200,

'data' => [

'message' => 'Successfully logged out'

],

'err' => null

];

return response()->json($data);

}/**

* Renewal process to make JWT reusable after expiry date.

* @return JsonResponse

*/

public function refresh(): JsonResponse

{

$data = [

'status' => true,

'code' => 200,

'data' => [

'_token' => auth()->refresh()

],

'err' => null

];

return response()->json($data, 200);

}

then we catch JWT related errors in our Exception Handler file and set the feedbacks. It must look exactly like this;

....use Illuminate\Http\Request;

use Illuminate\Http\Response;

use Tymon\JWTAuth\Exceptions\TokenExpiredException;

use Tymon\JWTAuth\Exceptions\TokenInvalidException;

use Tymon\JWTAuth\Exceptions\TokenBlacklistedException;

use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

...

/**

* Render an exception into an HTTP response.

*

* @param Request $request

* @param \Exception $exception

* @return Response

*/

public function render($request, Exception $exception) :Response

{

if ($exception instanceof UnauthorizedHttpException) {

$preException = $exception->getPrevious();

if ($preException instanceof

TokenExpiredException) {

return response()->json([

'data' => null,

'status' => false,

'err_' => [

'message' => 'Token Expired',

'code' =>1

]

]

);

}

else if ($preException instanceof

TokenInvalidException) {

return response()->json([

'data' => null,

'status' => false,

'err_' => [

'message' => 'Token Invalid',

'code' => 1

]

]

);

} else if ($preException instanceof

TokenBlacklistedException) {

return response()->json([

'data' => null,

'status' => false,

'err_' => [

'message' => 'Token Blacklisted',

'code' => 1

]

]

);

}

if ($exception->getMessage() === 'Token not provided') {

return response()->json([

'data' => null,

'status' => false,

'err_' => [

'message' => 'Token not provided',

'code' => 1

]

]

);

}else if( $exception->getMessage() === 'User not found'){

return response()->json([

'data' => null,

'status' => false,

'err_' => [

'message' => 'User Not Found',

'code' => 1

]

]

);

}

}

return parent::render($request, $exception);

}




</code>




and so we can now run tests on the postman. First, we start the project via Artisan CLI.

<code>

php artisan serve

then our project is running on http://127.0.0.1:8000.

Next Generation Use Cases of Edge Computing hbspt.cta.load(6512256, ’96b2ccc6-49a1-425b-adf9-de1537a41e43′, {});

You may be interested

The Ultimate CDN (Content Delivery Network) Guide 2022
CDN
4172 views
CDN
4172 views

The Ultimate CDN (Content Delivery Network) Guide 2022

medianova - February 8, 2022

The Ultimate CDN Guide - Everything About Content Delivery Network 2022 You probably know what CDN (Content Delivery Network) stands for. You may also be aware of…

The Essential CDN Glossary
CDN
10476 views
CDN
10476 views

The Essential CDN Glossary

Nadia Benslimane - November 21, 2019

Why Have We Decided To Create a CDN Glossary? Whether you are new to the world of CDN, or have been involved in it for years, there…

Ultimate Video Streaming Checklist for Businesses
Live Streaming
22 views
Live Streaming
22 views

Ultimate Video Streaming Checklist for Businesses

Sıla Saltoğlu - June 16, 2022

Ultimate Streaming Checklist for Businesses Video streaming services have already become part of the modern world. Standard entertainment habits have rapidly evolved with the digital transformation.  As…

API Security in Numbers 2022
security
115 views
security
115 views

API Security in Numbers 2022

Sıla Saltoğlu - May 24, 2022

API Caching Benefits for E-commerce
CDN
191 views
CDN
191 views

API Caching Benefits for E-commerce

Sıla Saltoğlu - May 9, 2022

The Benefits of API Caching for E-commerce In today's digital age, e-commerce is an essential part of many businesses. Whether we're shopping for clothing, electronics, or even…

Most from this category

The Essential CDN Glossary
CDN
10476 views
10476 views

The Essential CDN Glossary

Nadia Benslimane - November 21, 2019
How to Use Webinars to Boost Business Growth
How To
251 views
251 views

How to Use Webinars to Boost Business Growth

Sıla Saltoğlu - April 14, 2022
Enhance Live Streaming with 10 Tips
CDN
289 views
289 views

Enhance Live Streaming with 10 Tips

Sıla Saltoğlu - March 23, 2022
How does Live Commerce Shape E-commerce?
e-commerce
507 views
507 views

How does Live Commerce Shape E-commerce?

Sıla Saltoğlu - March 9, 2022