Pendahuluan
Melengkapi materi sebelumnya, dimana kita akan menemui beberapa masalah ketika mengintegrasikan antara API dengan NuxtJS-nya atau mungkin nantinya juga akan ditemui ketika mengintegrasi dengan Svelte. Materi ini akan membahas bagaimana cara melakukan cors handling di Lumen dan kita akan membuat fitur lainnya, yakni mengambil data atau fetching data user yang sedang login dan membuat fitur logout di Lumen.
Luputnya penulis dalam mengingat bahwa masalah ini akan ditemukan dikemudian hari, sehingga kita tidak membahasnya pada artikel sebelumnya. Tapi sebuah bentuk kesyukuran karena bisa menjadi sebuah materi baru lagi. Jadi, apabila kedepannya teman-teman bingung dalam mengikuti rangkaian materinya, saya akan menyertakan link materi sebelumnya pada pendahuluan.
Baca Juga: Membuat Aplikasi Ekspedisi Lumen 6 #3: Validation & Login
Cors Handling di Lumen
Sebuah permasalahan baru akan kita hadapi ketika mengerjakan sebuah aplikasi dengan project yang berbeda antara backend dalam hal ini adalah API dan frontend-nya. Masalah ini disebabkan karena browser meminta authority dari sumber data, apakah domain ini atau project ini diberikan izin untuk mengambil data atau tidak.
Ada beberapa teknik yang bisa dilakukan dalam meng-handle cors, salah satunya melalui backend itu sendiri dengan memberikan response berupa header. Berdasarkan aplikasi yang kita miliki, untuk memberikan headers kepada semua request yang masuk, maka kita akan menggunakan Middleware. Mengapa menggunakan Middleware? Karena akan sangat merepotkan, jika setiap method harus kita sertakan sebuah headers secara manual.
Middleware akan kita manfaatkan untuk menerapkan sebuah aturan secara global, sehingga aturan ini akan diikut sertakan pada semua route yang ada. Buat middleware baru bernama CorsMiddleware.php
di dalam folder app/Http/Middleware
dan tambahkan code berikut
<?php
namespace App\Http\Middleware;
use Closure;
class CorsMiddleware
{
/**
* Run the request filter.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
//RULE HEADERSNYA HARUS KITA SET SECARA SPESIFIK SEPERTI INI
$headers = [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Max-Age' => '86400',
'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With'
];
//TAPI JIKA METHOD YANG MASUK ADALAH OPTIONS
if ($request->isMethod('OPTIONS')) {
//MAKA KITA KEMBALIKAN BAHWA METHOD TERSEBUT ADALAH OPTIONS
return response()->json('{"method": "OPTIONS"}', 200, $headers);
}
//SELAIN ITU, KITA AKAN MENERUSKAN RESPONSE SEPERTI BIASA DENGAN MENGIKUT SERTAKAN HEADERS YANG SUDAH DITETAPKAN.
$response = $next($request);
foreach ($headers as $key => $row) {
$response->header($key, $row);
}
return $response;
}
}
Untuk mengaktifkan Middleware ini, buka file bootstrap/app.php
dan tambahkan code
$app->middleware([
App\Http\Middleware\CorsMiddleware::class
]);
Fetch Logged In & Logout User
Authentication yang akan kita terapkan di NuxtJS memiliki sebuah rule dimana ketika authentication tersebut berhasil, maka dia akan secara otomatis melakukan fetching users yang sedang login. Hal ini luput dari ingatan saya sehingga tidak dituliskan pada artikel sebelumnya.
Adapun cara untuk membuat fitur fetching data user yang sedang login, buka file UserController.php
dan tambahkan method berikut
public function getUserLogin(Request $request)
{
return response()->json(['status' => 'success', 'data' => $request->user()]);
}
Penjelasan: $request->user()
akan mengambil data user yang sedang login.
Definisikan routing-nya dengan menambahkan code berikut di dalam file routes/web.php
$router->get('/users/login', 'UserController@getUserLogin');
$router->post('/logout', 'UserController@logout'); //KITA TAMBAHKAN ROUTE LOGOUT SEKALIAN
Kemudian skenario untuk logout-nya adalah kita akan mengubah value api_token
dari user yang sedang login menjadi null. Buka kembali file UserController.php
dan tambahkan method
public function logout(Request $request)
{
$user = $request->user(); //GET USER YANG SEDANG LOGIN
$user->update(['api_token' => null]); //UPDATE VALUENYA JADI NULL
return response()->json(['status' => 'success']);
}
[ISSUE] Token Authorization
Ada sedikit masalah ketika format authorization yang dikirim memiliki lebih dari 1 spasi diantara kata Bearer dan token-nya itu sendiri. Masalah tersebut adalah fungsi explode akan menghasilkan lebih dari 2 array, sehingga array dengan key 1 bukan berisi token tapi string kosong.
Untuk mengatasi hal ini, buka file AuthServiceProvider.php
yang berada di dalam folder app/Providers
dan modifikasi block code yang memiliki return statement menjadi.
return User::where('api_token', end($explode))->first();
Penjelasan: Fungsi end adalah built-in dari PHP, dimana akan mengambil value dari index array terakhir.
[ISSUE] Routing Users
Ada sedikit permasalahan yang akan kita temukan berkaitan dengan fungsi untuk mengambil data user. Routing antara get user berdasarkan id dan get user berdasarkan yang sedang login akan saling tumpang tindih jika posisi route dari user yang sedang login berada di bawah route untuk mengambil user berdasarkan id. Adapun errornya akan terlihat seperti berikut
Untuk mengatasinya, cukup ganti posisinya dimana route user login ditempatkan di atas route get user. Buka file routes/web.php
dan modifikasi menjadi
$router->get('/users', 'UserController@index');
$router->post('/users', 'UserController@store');
$router->get('/users/login', 'UserController@getUserLogin'); //PINDAHKAN ROUTE INI
$router->get('/users/{id}', 'UserController@edit'); // DI ATAS ROUTE INI
$router->put('/users/{id}', 'UserController@update');
$router->delete('/users/{id}', 'UserController@destroy');
[ISSUE] Delete Data Users
Kendala yang akan kita temukan ketika melakukan penghapusan data pada user yang tidak memiliki gambar atau foto adalah sebuah response error pada code unlink
karena fungsi ini tidak menemukan data gambar yang akan dihapus. So, untuk mengatasinya, buka file UserController.php
dan modifikasi method destroy
menjadi
public function destroy($id)
{
$user = User::find($id);
if ($user->photo) {
unlink(base_path('public/images/' . $user->photo));
}
$user->delete();
return response()->json(['status' => 'success']);
}
[ISSUE] Validation on Update Users
Password adalah bagian penting bersifat opsional pada fitar edit data user, karena data password melalui proses encrypt, sehingga kita menggunakan logic dimana ketika password kosong, maka tidak perlu untuk memperbaharui data tersebut. Seluruh logic ini sudah direalisasikan, akan tetapi pada bagian validasi, kita lupa menghapus atau mengubahnya menjadi nullable, sehingga data password masih bersifat required.
Untuk mengatasinya, modifikasi line validasi password pada method update
menjadi
'password' => 'nullable|string|min:6',
[ISSUE] Search Data Users
Salah satu fitur yang terlupakan ketika membuat API data users pada episode Lumen adalah fitur pencarian data berdasarkan nama users. Sangat disayangkan jika materi ini harus diangkat pada materi baru, sehingga fitur ini saya anggap sebagai issue saja, jadi dalam penulisan bisa disisipkan pada seri yang sudah release.
Buka file UserController.php
dan modifikasi method index
menjadi
public function index(Request $request)
{
$users = User::orderBy('created_at', 'desc')->when($request->q, function($users) use($request) {
$users = $users->where('name', 'LIKE', '%' . $request->q . '%');
})->paginate(10);
return response()->json(['status' => 'success', 'data' => $users]);
}
Baca Juga: Membuat Aplikasi Ekspedisi Lumen 6 #2: Authentication & Manage Users
Kesimpulan
Sepanjang artikel ini kita telah belajar banyak hal baru ketika mengerjakan sebuah aplikasi, dimana masalah yang biasanya ditemukan seperti cors handling sudah berhasil kita selesaikan dengan lancar. Kita juga telah belajar bagaimana mengambil data user yang sedang login dan lain sebagainya.
Adapun dokumentasi code dari artikel ini bisa dilihat di Github.
Comments