Tutorial Laravel Rest API - #4 - Membuat Module Login

Artikel ini merupakan series dari Tutorial Authentication Dengan Laravel Sanctum dan Unit Testing, disini kita belajar membuat module login selain membuat rest api kita juga menuliskan sebuah unit test untuk module tersebut.

Rafi Taufiqurrahman
Dipublish 19/10/2024

Pendahuluan

Pada artikel kali ini, kita akan sama - sama membuat sebuah module login yang kita bagi menjadi beberapa langkah diatanya sebagai berikut :

  1. Membuat Controller Login
  2. Membuat Route Login
  3. Membuat Test Login
  4. Uji Coba Restapi Login

Membuat Controller Login

Silahkan teman - teman buka terminal-nya, kemudian jalankan perintah berikut ini :

Terminal
php artisan make:controller Api/LoginController -i

Jika perintah diatas berhasil dijalankan, maka kita akan mendapatkan sebuah file yang terletak di app/Http/Controllers/Api dengan nama LoginController.php, kemudian dari perintah artisan diatas kita menambahkan sebuah flag -i yang artinya pada LoginController.php kita hanya akan memiliki sebuah method __invoke didalamnya, selanjutnya silahkan buka file tersebut kemudian tambahkan kodenya menjadi seperti berikut ini.

LoginController.php
<?php

namespace App\Http\Controllers\Api;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;

class LoginController extends Controller
{
    /**
     * Handle the incoming request.
     */
    public function __invoke(Request $request)
    {
        // validate request
        $request->validate([
            'email' => 'required|email',
            'password'=> 'required',
        ]);

        // get user by request email
        $user = User::where('email', $request->email)->first();

        // check if user exists and password is correct
        if(!$user || !Hash::check($request->password, $user->password))
            return response()->json([
                'message' => 'The provided credentials are incorrect.'
            ], 401);

        // create token
        $token = $user->createToken('auth_token')->plainTextToken;

        // return response
        return response()->json([
            'access_token' => $token,
            'token_type' => 'Bearer',
        ]);
    }
}

Dari kode diatas, pertama kita lakukan import model User.

LoginController.php
use App\Models\User;

Kemudian kita membuat validasi data terlebih dahulu, sebelum melakukan pencarian data user menggunakan method validate.

LoginController.php
// validate request
$request->validate([
    'email' => 'required|email',
    'password'=> 'required',
]);

Selanjutnya jika request yang kita kirimkan sudah sesuai dengan kriteria validasi yang kita definisikan, maka kita akan melakukan proses pencarian data user sesuai dengan request email yang kita kirimkan, menggunakan method where . kemudian kita tampilkan data tersebut menggunakan method first.

LoginController.php
// get user by request email
$user = User::where('email', $request->email)->first();

Berikutnya kita lakukan pengecekan request password yang kita kirimkan, jika request yang kita kirimkan tidak sesuai dengan password yang dimiliki user, maka kita tampilkan sebuah response json dengan key message dan status code 401.

LoginController.php
// check if user exists and password is correct
if(!$user || !Hash::check($request->password, $user->password))
    return response()->json([
        'message' => 'The provided credentials are incorrect.'
    ], 401);

Jika data user ditemukan ataupun request password yang diberikan sesuai, maka kita memanfaat method createToken untuk mengenerate token untuk user tersebut.

LoginController.php
// create token
$token = $user->createToken('auth_token')->plainTextToken;

Terakhir, kita tampilkan data dalam bentuk format Json.

LoginController.php
// return response
return response()->json([
    'access_token' => $token,
    'token_type' => 'Bearer',
]);

Membuat Route Login

Setelah berhasil membuat sebuah controller Login, sekarang kita akan lanjutkan untuk pembuatan route-nya, silahkan teman - teman buka file routes/api.php, kemudian ubah kode-nya menjadi seperti berikut ini.

api.php
<?php

use App\Http\Controllers\Api\LoginController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\RegisterController;

Route::post('/register', RegisterController::class);
Route::post('/login', LoginController::class);

Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');

Pada kode diatas, kita menambahkan sebuah route baru dengan method post yang kita arahkan ke url api/login, untuk memastikan route yang kita buat telah berfungsi, teman - teman bisa jalankan perintah berikut ini pada terminal-nya.

Terminal
php artisan r:l

Setelah perintah artisan diatas dijalankan, maka kita akan mendapatkan output, kurang lebih seperti berikut ini.

Terminal
GET|HEAD   / ............................................................................................................................ 
POST       api/login ................................................................................................ Api\LoginController
POST       api/register .......................................................................................... Api\RegisterController
GET|HEAD   api/user ..................................................................................................................... 
GET|HEAD   sanctum/csrf-cookie ........................................ sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
GET|HEAD   storage/{path} ................................................................................................. storage.local
GET|HEAD   up ...........................................................................................................................

Membuat Test Login

Setelah berhasil membuat route Login, sekarang kita akan lanjutkan untuk pembuatan test-nya, disini kita akan menggunakan PHPUnit untuk membuat test-nya. Silahkan teman - teman buka terminal-nya, kemudian jalankan perintah berikut ini :

Terminal
php artisan make:test LoginControllerTest

Jika perintah diatas berhasil dijalankan, maka kita akan mendapatkan sebuah file yang terletak di tests/Feature dengan nama LoginControllerTest, selanjutnya silahkan buka file tersebut kemudian tambahkan kodenya menjadi seperti berikut ini.

LoginControllerTest.php
<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class LoginControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_user_can_login_with_correct_credentials()
    {
        // create a user with factory
        User::factory()->create([
            'email' => 'raf@dev.com',
            'password' => bcrypt('password'),
        ]);

        // send json post request to login with correct credentials
        $response = $this->postJson('/api/login', [
            'email' => 'raf@dev.com',
            'password' => 'password',
        ]);

        // assert that the response is a 200 with a json structure containing an access token and a token type
        $response->assertStatus(200)
            ->assertJsonStructure([
                'access_token',
                'token_type',
            ]);
    }

    public function test_user_cannot_login_with_incorrect_credentials()
    {
        // create a user with factory
        User::factory()->create([
            'email' => 'raf@dev.com',
            'password' => bcrypt('password'),
        ]);

        // send json post request to login with incorrect credentials
        $response = $this->postJson('/api/login', [
            'email' => 'test@example.com',
            'password' => 'wrongpassword',
        ]);

        // assert that the response is a 401 with a json structure containing an message
        $response->assertStatus(401)
            ->assertJson([
                'message' => 'The provided credentials are incorrect.'
            ]);
    }

    public function test_login_validation_fails_with_missing_fields()
    {
        // send json post request to login with empty array
        $response = $this->postJson('/api/login', []);

        // assert that the response is a 422 with json validation errors for the email and password
        $response->assertStatus(422)
            ->assertJsonValidationErrors(['email', 'password']);
    }
}

Didalam class LoginControllerTest, kita membuat 3 buah method baru diantaranya sebagai berikut :

  1. test_user_can_login_with_correct_credentials
  2. test_user_cannot_login_with_incorrect_credentials
  3. test_login_validation_fails_with_missing_fields

Dari kode diatas, pertama kita lakukan import model user.

LoginControllerTest.php
use App\Models\User;

Selanjutnya kita import juga sebuah trait yang akan kita gunakan, disini kita menggunakan trait RefreshDatabase;.

LoginControllerTest.php
use Illuminate\Foundation\Testing\RefreshDatabase;

untuk penggunaan trait tersebut kita menggunakan method use.

LoginControllerTest.php
use RefreshDatabase;

Method test_user_can_login_with_correct_credentials

Method ini kita gunakan untuk memastikan bahwa kita bisa melakukan login dengan menggunakan kredensial yang benar.

LoginControllerTest.php
public function test_user_can_login_with_correct_credentials()
{
    // create a user with factory
    User::factory()->create([
        'email' => 'raf@dev.com',
        'password' => bcrypt('password'),
    ]);

    // send json post request to login with correct credentials
    $response = $this->postJson('/api/login', [
        'email' => 'raf@dev.com',
        'password' => 'password',
    ]);

    // assert that the response is a 200 with a json structure containing an access token and a token type
    $response->assertStatus(200)
        ->assertJsonStructure([
            'access_token',
            'token_type',
        ]);
}

Pada kode diatas, pertama - tama kita mendaftarkan user baru dengan sebuah factory yang telah disediakan oleh laravel, disini kita set email nya dengan raf@dev.com dan password kita set dengan password.

LoginControllerTest.php
// create a user with factory
User::factory()->create([
    'email' => 'raf@dev.com',
    'password' => bcrypt('password'),
]);

selanjutnya, kita menggunakan method postJson untuk melakukan request dengan method POST ke sebuah route /api/login, dengan body yang berisi data yang diperlukan untuk login, yaitu email dan password. Di sini kita menggunakan kredensial yang sama dengan yang telah kita buat sebelumnya.

LoginControllerTest.php
// send json post request to login with correct credentials
$response = $this->postJson('/api/login', [
    'email' => 'raf@dev.com',
    'password' => 'password',
]);

Setelah request dikirim, kita menggunakan method assertStatus untuk memastikan bahwa respons dari request tersebut memiliki status kode 200, yang berarti request berhasil dilakukan. Selain itu, kita juga menggunakan method assertJsonStructure untuk memverifikasi bahwa respons Json yang kita terima, memiki struktur yang sesuai dengan response yang kita definiskan di controller. disini kita mendefinisikannya dengan key access_token dan token_type.

LoginControllerTest.php
// assert that the response is a 200 with a json structure containing an access token and a token type
$response->assertStatus(200)
    ->assertJsonStructure([
        'access_token',
        'token_type',
    ]);

Method test_user_cannot_login_with_incorrect_credentials

Method ini kita gunakan untuk memastikan bahwa kita tidak dapat melakukan login dengan menggunakan kredensial yang salah.

LoginControllerTest.php
public function test_user_cannot_login_with_incorrect_credentials()
{
    // create a user with factory
    User::factory()->create([
        'email' => 'raf@dev.com',
        'password' => bcrypt('password'),
    ]);

    // send json post request to login with incorrect credentials
    $response = $this->postJson('/api/login', [
        'email' => 'test@example.com',
        'password' => 'wrongpassword',
    ]);

    // assert that the response is a 401 with a json structure containing an message
    $response->assertStatus(401)
        ->assertJson([
            'message' => 'The provided credentials are incorrect.'
        ]);
}

Pada kode diatas, pertama - tama kita mendaftarkan user baru dengan sebuah factory yang telah disediakan oleh laravel, disini kita set email nya dengan raf@dev.com dan password kita set dengan password.

LoginControllerTest.php
// create a user with factory
User::factory()->create([
    'email' => 'raf@dev.com',
    'password' => bcrypt('password'),
]);

Selanjutnya, kita menggunakan method postJson untuk melakukan request dengan method POST ke sebuah route /api/login, dengan body yang berisi data yang tidak terdaftar untuk login, yaitu email yang kita set dengan test@example.com dan password yang kita set dengan wrongpassword.

LoginControllerTest.php
// send json post request to login with incorrect credentials
$response = $this->postJson('/api/login', [
    'email' => 'test@example.com',
    'password' => 'wrongpassword',
]);

Setelah request dikirim, kita menggunakan method assertStatus untuk memastikan bahwa respons dari request tersebut memiliki status kode 401, yang berarti bahwa akses ditolak karena kredensial tidak valid. Selain itu, kita juga menggunakan method assertJson untuk memverifikasi bahwa respons Json kita menampilkan sebuah pesan bahwa kredensial kita tidak sesuai.

LoginControllerTest.php
// assert that the response is a 401 with a json structure containing an message
$response->assertStatus(401)
    ->assertJson([
        'message' => 'The provided credentials are incorrect.'
    ]);

Method test_login_validation_fails_with_missing_fields

Method ini kita gunakan untuk memastikan bahwa sistem memberikan respons yang sesuai ketika ada field yang hilang saat melakukan login.

LoginControllerTest.php
public function test_login_validation_fails_with_missing_fields()
{
    // send json post request to login with empty array
    $response = $this->postJson('/api/login', []);

    // assert that the response is a 422 with json validation errors for the email and password
    $response->assertStatus(422)
        ->assertJsonValidationErrors(['email', 'password']);
}

Pada kode di atas, kita menggunakan method postJson untuk melakukan request dengan method POST ke sebuah route /api/login, dengan mengirimkan body yang kosong .

LoginControllerTest.php
// send json post request to login with empty array
$response = $this->postJson('/api/login', []);

Setelah request dikirim, kita menggunakan method assertStatus untuk memastikan bahwa respons dari request tersebut memiliki status kode 422, yang menunjukkan bahwa ada kesalahan validasi. Selain itu, kita juga menggunakan method assertJsonValidationErrors untuk memverifikasi bahwa respons Json yang kita terima menunjukkan kesalahan validasi untuk kolom email dan password.

LoginControllerTest.php
// assert that the response is a 422 with json validation errors for the email and password
$response->assertStatus(422)
    ->assertJsonValidationErrors(['email', 'password']);

Menjalankan Test

Setelah berhasil menuliskan Unit Test, disini kitakan akan menjalankan test yang telah kita tulis. Silahkan teman - teman buka terminal-nya, kemudian jalankan perintah berikut ini:

Terminal
php artisan test tests/Feature/LoginControllerTest.php

Pada kode diatas, kita menjalankan sebuah test secara spesifik dengan memasukan nama file beserta foldernya.

Terminal
tests/Feature/LoginControllerTest.php

jika perintah diatas, berhasil dijalankan kita akan menerima output kurang lebih berikut ini, yang menandakan semua test yang kita buat berhasil tanpa ada error.

Terminal
PASS  Tests\Feature\LoginControllerTest
✓ user can login with correct credentials                                                                                           0.31s  
✓ user cannot login with incorrect credentials                                                                                      0.01s  
✓ login validation fails with missing fields                                                                                        0.01s  

Tests:    3 passed (9 assertions)
Duration: 0.39s

Uji Coba Rest Api Login

Setelah berhasil membuat test dan menjalankannya, disini kita akan lanjutkan melakukan uji coba rest api tersebut menggunakan Postman. Silahkan teman - teman buka aplikasi Postman, kemudian masukan url http://localhost:8000/api/login dan method-nya silahkan di set menjadi POST.

login-request

Kemudian silahkan teman - teman masuk tab Body dan pilih form-data, kemudian silahkan masukan key dan value seperti contoh dibawah ini.

Key Value
email raf@dev.com
password password

Selanjutnya, silahkan teman - teman klik tombol send, jika request berhasil dilakukan maka kita akan mendapatkan response seperti berikut ini.

Postman
{
    "access_token": "2|srLv7eLNc4nuK4E51NWZgkK8E6doalZw5tRyd93s59636dc5",
    "token_type": "Bearer"
}

register-success

Penutup

Setelah berhasil menyelesaikan pembuatan module login, pada artikel berikutnya kita akan lanjutkan untuk pembuatan module profile yang dimana module tersebut akan menjadi artikel terakhir dari series ini, semoga bermanfaat terimakasih :)

Artikel Lainnya

Beberapa artikel rekomendasi lainnya untuk menambah pengetahuan.

1
Tutorial Laravel Rest API - #5 - Membuat Module Profile
Artikel ini merupakan series dari Tutorial Authentication Dengan Laravel Sanctum dan Unit Testing, disini kita belajar membuat module profile selain membuat rest api kita juga menuliskan sebuah unit test untuk module tersebut.
2
Tutorial Laravel Rest API - #3 - Membuat Module Register
Artikel ini merupakan series dari Tutorial Authentication Dengan Laravel Sanctum dan Unit Testing, disini kita belajar membuat module registrasi selain membuat rest api kita juga menuliskan sebuah unit test untuk module tersebut.
3
Tutorial Laravel Rest API - #2 - Installasi Laravel Sanctum
Artikel ini merupakan series dari Tutorial Authentication Dengan Laravel Sanctum dan Unit Testing, disini kita akan mulai melakukan installasi laravel sanctum dan implementasi api token pada model user.
4
Tutorial Laravel Livewire - #9 - Membuat Module Product Dengan Livewire
Artikel ini merupakan series dari Tutorial Laravel Livewire Study Case Point Of Sales, disini kita akan membuat sebuah module product dengan livewire.
5
Tutorial Laravel Livewire - #6 - Memanfaatkan Salah Satu Magic Laravel Yaitu Eloquent Accessor
Artikel ini merupakan series dari Tutorial Laravel Livewire Study Case Point Of Sales, disini kita akan mengenal salah satu magic laravel yang sangat powerfull yaitu laravel accessor.
6
Tutorial Inertia Roles & Permissions - #2 - Installasi Project
Artikel ini merupakan series dari Tutorial Laravel Inertia Roles & Permissions, disini kita akan mulai melakukan installasi project laravel kita dari awal menggunakan composer.

JurnalKoding

Mulai asah skill dengan berbagai macam teknologi - teknologi terbaru seperti Laravel, React, Vue, Inertia, Tailwind CSS, dan masih banyak lagi.

© 2025 JurnalKoding, Inc. All rights reserved.