Hampir semua API menutup pintunya untuk tamu anonim: sebelum data diberikan, server menuntut bukti identitas lewat header. Bentuk buktinya bermacam-macam — bearer token, basic auth, API key — dan tiap layanan memilih caranya sendiri. HTTP Client menyediakan method khusus untuk tiap skema umum sehingga kita tidak perlu merangkai header secara manual. Seperti chapter sebelumnya, contoh di sini memakai fake yang memantulkan request balik, sehingga output yang kita lihat adalah header yang benar-benar terkirim ke server tujuan.

Bearer Token dengan withToken #

Skema paling umum di API modern adalah bearer token: header Authorization berisi nilai Bearer <token>. Method withToken() membangunnya dari potongan mentahnya:

php
<?php

use Illuminate\Support\Facades\Http;

Http::fake(fn ($request) => Http::response(['headers' => $request->headers()]));

$response = Http::withToken('YOUR_API_TOKEN')
    ->get('https://api.example.com/profil');

echo 'Authorization: '.$response->json('headers.Authorization.0')."\n";

Output yang Dihasilkan:

text
Authorization: Bearer YOUR_API_TOKEN

Kata Bearer ditambahkan otomatis sebagai prefix. Beberapa API memakai skema lain seperti Token — cukup kirim sebagai parameter kedua: withToken($token, 'Token').

Basic dan Digest Auth #

Untuk API lawas yang masih memakai HTTP Basic, withBasicAuth() menerima username dan password, lalu mengirimnya sebagai string yang di-encode base64:

php
<?php

$response = Http::withBasicAuth('[email protected]', 'rahasia')
    ->get('https://api.example.com/profil');

echo 'Authorization: '.$response->json('headers.Authorization.0')."\n";

Output yang Dihasilkan:

text
Authorization: Basic YnVkaUBleGFtcGxlLmNvbTpyYWhhc2lh

String panjang tersebut adalah hasil base64_encode('[email protected]:rahasia') — tepat seperti yang diharapkan spesifikasi HTTP Basic.

Saudaranya, withDigestAuth('[email protected]', 'rahasia'), bekerja dengan pola berbeda. Digest auth adalah protokol challenge-response: Guzzle mengirim request pertama tanpa kredensial, server menjawab 401 dengan challenge WWW-Authenticate: Digest ..., baru Guzzle menghitung hash respons dan mengirim ulang request dengan header Authorization: Digest .... Karena butuh server sungguhan yang mengirim challenge, contoh digest tidak bisa dipantulkan lewat fake sederhana — cukup tahu bahwa penulisannya sama: Http::withDigestAuth($user, $password)->get($url).

Header Kustom dan API Key #

Sisanya adalah header bebas. Method withHeaders() menerima array asosiatif, dan ada shortcut untuk dua header yang paling sering diatur — accept() untuk Accept serta withUserAgent() untuk User-Agent:

php
<?php

$response = Http::withHeaders([
    'X-Api-Key' => 'YOUR_API_KEY',
    'Accept' => 'application/json',
])->withUserAgent('AplikasiBudi/1.0')
    ->get('https://api.example.com/profil');

echo 'X-Api-Key: '.$response->json('headers.X-Api-Key.0')."\n";
echo 'Accept: '.$response->json('headers.Accept.0')."\n";
echo 'User-Agent: '.$response->json('headers.User-Agent.0')."\n";

Output yang Dihasilkan:

text
X-Api-Key: YOUR_API_KEY
Accept: application/json
User-Agent: AplikasiBudi/1.0

Sebagian layanan justru menuntut API key lewat query string, bukan header. Kita sudah tahu caranya dari chapter sebelumnya:

php
<?php

$response = Http::get('https://api.example.com/profil', ['api_key' => 'YOUR_API_KEY']);

echo 'url: '.$response->json('url')."\n";

Output yang Dihasilkan:

text
url: https://api.example.com/profil?api_key=YOUR_API_KEY

Pola Refresh Token: 401, Perbarui, Coba Lagi #

Token hidupnya terbatas — biasanya hitungan menit. Aplikasi nyata perlu menangani momen token kedaluwarsa: response 401 tiba, kita meminta token baru ke endpoint refresh, lalu mengulang request asal. Berikut pola lengkapnya yang teruji, memakai Http::sequence() untuk mensimulasikan urutan 401 lalu sukses:

php
<?php

use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;

Http::fake([
    'api.example.com/profil' => Http::sequence()
        ->push(['pesan' => 'Token kedaluwarsa'], 401)
        ->push(['nama' => 'Budi', 'token_dipakai' => 'TOKEN_BARU'], 200),
    'api.example.com/token/refresh' => Http::response(['token' => 'TOKEN_BARU'], 200),
]);

function ambilProfil(string $token): Response
{
    $response = Http::withToken($token)->get('https://api.example.com/profil');

    if ($response->status() === 401) {
        $tokenBaru = Http::post('https://api.example.com/token/refresh', [
            'token' => $token,
        ])->json('token');

        $response = Http::withToken($tokenBaru)->get('https://api.example.com/profil');
    }

    return $response;
}

$r = ambilProfil('TOKEN_LAMA');
echo 'status: '.$r->status()."\n";
echo 'nama: '.$r->json('nama')."\n";
echo 'token yang dipakai: '.$r->json('token_dipakai')."\n";

Output yang Dihasilkan:

text
status: 200
nama: Budi
token yang dipakai: TOKEN_BARU

Alurnya: request pertama memakai TOKEN_LAMA dan ditolak 401; blok if meminta token baru dari endpoint refresh; request kedua sukses. Pola manual seperti ini mudah dibaca dan diuji; di chapter Timeout dan Retries kita akan melihat versi otomatisnya lewat retry() dengan callback kondisi.

Identitas request sudah beres. Masalah berikutnya sangat praktis: jaringan lambat dan server yang kadang tidak menjawab — panggilan tanpa batas waktu akan menggantung seluruh proses, dan itulah urusan chapter berikutnya. Rujukan lengkap semua opsi autentikasi tersedia di dokumentasi HTTP Client .