Blog Tarikh Agustia

tarikhagustia.id Adalah sebuah situs pembelajaran tingkat lanjut

Membangun Microservices sederhana dengan PHP, NodeJS dan Docker – Bagian 2 (Authentication Service)

Membangun Microservice Sederhana dengan PHP NodeJS dan Docker

Assalamu’alaikum Wr. Wb Pada artikel kali ini saya akan melanjutkan materi tentang Membangun Microservices sederhana dengan PHP, NodeJS dan Docker. Pada bagian ini saya akan menjelaskan tentang pembuatan Authentication Service, oh iya sebelum ke materi FYI ya buat temen – temen bahwa domain blog saya telah di ubah dari blog.tarikhagustia.id ke tarikhagustia.id karena sesuatu dan lain hal.

Pada artikel bagian pertama, kita sudah membahas tentang arsitektur yang akan kita buat. Nah pada bagian ini admin akan membuat Authentication Service menggunakan PHP dengan Framework lumen. Mungkin ada temen – temen yang bertanya, “Bang kok pake PHP? kenapa ga pake golang atau semacamnya? kan lebih cocok.” ya karena saya sendiri belum bisa golang hehe 🙁 . Disini saya mencoba untuk memperlihatkan keberagaman dalam pembuatan microservice. Untuk Framework, temen – temen bebas memilih apa saja kebetulan saya pake Lumen karena saya sendiri sudah terbiasa dengan Laravel.

Tapi ni tapi… memakai PHP sebagai microservices bukanlah hal yang jelek, karena performance dari PHP sendiri mangkin kesini mangkin “Ngacir”.

Installasi Lumen

Disini saya ga bakal ngajarain hal – hal basic, jadi saya anggap temen – temen sudah bisa dalam melakukan installasi untuk Lumen Framework, kalo temen – temen ga tau cara install nya, cek official dokumentasi nya.

jadi pada pembuatan microservices ini saya akan membuat struktur folder seperti ini :

~/Documents/code/microservices/
- authentication
- products

untuk lokasi nya disesuaikan ya di lokasi komputer temen – temen, kebetulan saat membuat artikel ini saya pake Mac (Sombong amat …).

Oke, kemudian untuk menginstall lumen di dalam folder microservices, run command berikut :

composer create-project --prefer-dist laravel/lumen authentication

Seteleh terinstall pastikan temen – temen melakukan konfigurasi dasar, untuk konfigurasi dasar temen – temen bisa lihat di offical dokumentasi nya. Setelah terkonfigurasi dengan baik silahkan temen – temen buka project nya dengan Text Editor / IDE yang disukai, saat ini saya pakai PHPStrom sebagai IDE nya.

Selanjutnya dalam pembuatan service ini kita akan memakai packages https://github.com/tymondesigns/jwt-auth untuk melakukan generator token JWT, tambahkan package tersebut pada composer.json

...
"tymon/jwt-auth": "^1.0",
...

Pakai yang versi 1 keatas ya biar upto date gituloh, Kemudian jalankan composer update, untuk installasi lengkapnya silahkan baca dokumentasi lengkapnya di https://jwt-auth.readthedocs.io/en/develop/lumen-installation/

Jangan lupa dibaca juga ya quick start nya https://jwt-auth.readthedocs.io/en/develop/quick-start/

Kemudian pastikan lumen framework nya berjalan dengan sempurna dengan menjalankan perintah

php -S localhost:8000 -t public

Jika tidak ada error, maka lumen framework akan berjalan pada port 8000 dan akan memberikan response : Lumen (6.2.0) (Laravel Components ^6.0), jika tidak temen – temen bisa debugging sendiri, itung – itung latihan hehe ;).

Membuat End Point

Dalam pembuatan API pasti kita tidak asing lagi dengan kata End Point, kali ini kita akan membuat 2 endpoin yaitu :

  1. /auth/token (Memberikan response token)
  2. /auth/me (Memberikan informasi user yang telah login)

Pertama kita harus membuat controller, jika temen – temen mengikuti tutorial dari https://jwt-auth.readthedocs.io/en/develop/quick-start/ maka temen – temen tinggal ikuti saja. Mari kita buat AuthController.php (Karena dilumen ga bisa generate controller) jadi kita mesti buat secara manual.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    /**
     * Get a JWT via given credentials.
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $credentials = $request->only(['email', 'password']);

        if (! $token = Auth::attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        return $this->respondWithToken($token);
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json(Auth::user());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        Auth::logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => Auth::factory()->getTTL() * 60
        ]);
    }
}

Kemudian selanjutnya mari kita buat routes nya, edit file web.php dan tambahkan script berikut :

<?php


$router->get('/', function () use ($router) {
    return $router->app->version();
});

$router->post('/token', 'AuthController@login');
$router->get('/me', 'AuthController@me');

disini kita tidak akan menggunakan prefix /auth, karena nantinya prefix auth akan dihanle oleh Nginx Proxy, jadi nanti semua request yang mempunyai prefix /auth akan diarahkan ke service ini.

Kemudian cobalah untuk mencoba melakukan hit kepada end point /me, temen – temen bisa pakai postman atau browser, kalo saya biasanya pakai postman. Maka seharusnya temen – temen akan mendapatkan respose seperti ini :

Unauthorized.

Hal ini dikarenakan kita harus melakukan authentikasi terlebih dahulu sebelum mengakses endpoint /me.

Nah untuk mempermudah aplikasi yang menjadi Front End API kita nanti maka response error yang akan kita berikan diusahaakan seragam dan dapat dimengerti, kali ini kita akan membuat respose nya menjadi json. Untuk merubah Error Unauthorized Response, edit file app/Http/Middleware/Authenticate.php menjadi

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;

class Authenticate
{
    /**
     * The authentication guard factory instance.
     *
     * @var \Illuminate\Contracts\Auth\Factory
     */
    protected $auth;

    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Auth\Factory  $auth
     * @return void
     */
    public function __construct(Auth $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if ($this->auth->guard($guard)->guest()) {
            return response()->json([
                'status_code' => 401,
                'message' => 'Unauthorized'
            ], 401);
        }

        return $next($request);
    }
}

Setelah disave, kemudian kita Hit lagi endpoint /me, seharusnya menampilkan pesan error berikut :

{
    "status_code": 401,
    "message": "Unauthorized"
}

Untuk melakukan pengujian pada end point /token, tentunya kita perlu data contoh, buatlah seeder untuk menambah tabel user, kemudian lakukan migrate, untuk file migration dan seeder nya lihat script berikut :

// Migration
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class UserTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}
// Seeder
<?php

use App\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;

class UserTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $user = new User;
        $user->name = "Fulan";
        $user->email = '[email protected]';
        $user->password = Hash::make('[email protected]');
        $user->save();
    }
}

setelah terbentuk 1 data didalam database, kemudian kita harus manambahkan config ke auth.php, dikarenakan lumen ini config nya tidak di expose, maka kita harus mengcopy dari file vendor ke config/auth.php, copy script berikut :

<?php

use App\User;

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */
    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],


    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */
    'guards' => [
        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
        ],
    ],

    // optional, if use eloquent
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => User::class,
        ]
    ],
];

Kemudian coba test dengan postman untuk end point /token, dengan username dan password sesuai seeder diatas, jika berhasil response nya akan seperti ini :

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODAwMFwvdG9rZW4iLCJpYXQiOjE1NzYyMjU0ODMsImV4cCI6MTU3NjIyOTA4MywibmJmIjoxNTc2MjI1NDgzLCJqdGkiOiJnYkJqNEJYYnI2a2J4NGZ5Iiwic3ViIjoxLCJwcnYiOiI4N2UwYWYxZWY5ZmQxNTgxMmZkZWM5NzE1M2ExNGUwYjA0NzU0NmFhIn0.O2C6Vf88QHgk87jKFIvwSbQr-_DGOgeAhMMmg0_DdAg",
    "token_type": "bearer",
    "expires_in": 3600
}

Mungkin begitu saja materi kali ini, jika ada yang kurang jelas bisa PM admin, mohon maaf jika masih banyak kekurangan.

Tarikh Agustia

Saya adalah seorang yang tertarik dibidang teknologi dan informasi, khususnya dalam software engineering, penyuka kopi juga tapi bukan kopi senja, kopi apa aja yang penting bisa diseduh. pokonya kalo yang Mantap - Mantap saya suka aja sih.

Kembali ke atas