ahmadajah03 Sat Nov 2020 1 year ago

Secure Rest API dengan JWT Authentication di Laravel 8x

Token Web SON adalah  metode RFC 7519 standar industri terbuka  untuk mewakili klaim secara aman antara dua pihak. Pada artikel ini, saya akan menunjukkan cara mengamankan Laravel API dengan JWT. Saya sedang menguji Laravel 8.6.0 .

Instal Laravel dan Konfigurasi Dasar

Setiap proyek Laravel membutuhkan hal ini. Itu sebabnya saya menulis artikel tentang topik ini. Silakan lihat bagian ini dari sini:  Instal Laravel dan Konfigurasi Dasar .

Setelah menyelesaikan konfigurasi dasar, jalankan migrasi:

php artisan migrate

Instal Paket JWT

Kami akan menggunakan paket tymon / jwt-auth . Jalankan perintah komposer ini untuk menginstal paket ini:

composer require tymon/jwt-auth

Anda perlu menerbitkan file konfigurasi untuk JWT menggunakan perintah berikut:

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

Token JWT akan ditandatangani dengan kunci enkripsi. Jalankan perintah ini untuk menghasilkan kunci:

php artisan jwt:secret

Kuncinya akan disimpan dalam .env file seperti:

JWT_SECRET=secret-key

Ubah Model User

Kita perlu mendefinisikan dua metode dalam app/Models/User.php file. Metodenya adalah getJWTIdentifier() dan getJWTCustomClaims(). Model pengguna perlu mengimplementasikan JWTSubject.

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use HasFactory, Notifiable;

    /**
     * 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',
    ];

    /**
     * Get JWT identifier.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

Config Auth Guard

Kita perlu menetapkan penjaga autentikasi JWT sebagai penjaga API dalam config/auth.phpfile.

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
        'hash' => false,
    ],
],

Buat Controller

Mari buat pengontrol bernama AuthController:

 php artisan make:controller AuthController

Sekarang buka pengontrol dari app\Http\Controllers dan tempel kode ini:

<?php

namespace App\Http\Controllers;

use Validator;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

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

    /**
     * Register a User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|between:2,100',
            'email' => 'required|string|email|max:100|unique:users',
            'password' => 'required|string|confirmed|min:6',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors()->toJson(), 400);
        }

        $user = User::create(array_merge(
            $validator->validated(),
            ['password' => bcrypt($request->password)]
        ));

        return response()->json([
            'message' => 'User successfully registered',
            'user' => $user
        ], 201);
    }


    /**
     * Get a JWT token via given credentials.
     *
     * @param \Illuminate\Http\Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required|string|min:6',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        if (!$token = $this->guard()->attempt($validator->validated())) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

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

    /**
     * Get the authenticated User
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function profile()
    {
        return response()->json($this->guard()->user());
    }

    /**
     * Log the user out (Invalidate the token)
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        $this->guard()->logout();

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

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken($this->guard()->refresh());
    }

    /**
     * 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' => $this->guard()->factory()->getTTL() * 60
        ]);
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\Guard
     */
    public function guard()
    {
        return Auth::guard('api');
    }
}

Saya telah mengatur beberapa fungsi sederhana di controller.

Tentukan Route API

Buka file routes/api.php dan tentukan route berikut:

<?php

use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;

Route::group(['prefix' => 'auth', 'middleware' => 'api'], function () {
    Route::post('register', [AuthController::class, 'register']);
    Route::post('login', [AuthController::class, 'login']);
    Route::post('refresh', [AuthController::class, 'refresh']);
    Route::get('profile', [AuthController::class, 'profile']);
    Route::post('logout', [AuthController::class, 'logout']);
});

Test API

Kami telah menyelesaikan semua tugas. Mari buka Postman dan mulai menguji API kita.

Register:

Login: Kita harus meneruskan token sebagai kolom header "Authorization: Bearer Token".

Segarkan Token:

Data Profil:

Keluar:

Tutorial selesai. Anda dapat mengunduh proyek ini dari GitHub . Terima kasih.🙂

 

auth api with JWT laravel example laravel