ল্যারাভেলে REST API তৈরি এবং অথেনটিকেশন

ল্যারাভেলে কিভাবে সিম্পল অ্যাপ তৈরি করা যায় তা দেখেছি। এর আগে আমরা একটা সিম্পল নোট অ্যাপ তৈরি করেছি। এবার দেখব ঐ নোট গুলো কিভাবে REST API ব্যবহার করে এক্সেস করা যায়। এই লেখাটা পড়ার আগে ল্যারাভেলে পূর্ণাঙ্গ CRUD – নোট অ্যাপ লেখাটা পড়লে ভালো হবে। ঐখানে আমরা দেখেছি কিভাবে ফ্রন্টয়েন্ড থেকে পোস্ট তৈরি, আপডেট, ডিলেট ইত্যাদি করা যায়। আমরা এবার একই কাজ API এর মাধ্যমে করব। তার জন্য নতুন একটা ল্যারাভেল প্রজেক্ট তৈরি করে নিব।

composer create-project laravel/laravel note-api
cd note-api

এরপর আমরা Note নামে একটা মডেল তৈরি করব। মডেলের পাশা পাশি মাইগ্রেশন ফাইল এবং কন্ট্রোলার তৈরি করার জন্য এভাবে কমান্ড লিখবঃ

php artisan make:model Note -cmr

নোট ডেটাবেজ স্কিমা

database/migrations/…._create_notes_table.php ফাইল ওপেন করব। ডিফল্ট ভাবে ডেটাবেজ স্কিমায় ID এবং টাইমস্ট্যাপ যোগ থাকে। আমরা আরো দুইটা কলাম যোগ করব। title এবং note:

Schema::create('notes', function (Blueprint $table) {
           $table->id();
           $table->string('title');
           $table->longText('note');
           $table->timestamps();
       });

ডেটাবেজ মাইগ্রেশন

ডেটাবেজ স্কিমা তৈরির পর মাইগ্রেশন করে নিব। তাহলে ডেটাবেজে Note টেবিল তৈরি হবে। ডেটাবেজ সম্পর্কে বিস্তারিত জানা যাবে এই লেখায়। যদি আপনি ভিজুয়াল স্টুডিও কোড ব্যবহার করেন, SQLite Viewer এই এক্সটেনশনটা ব্যবহার করতে পারেন। এটি ব্যবহার করে SQLite ডেটাবেজ ভিজুয়ালি দেখা যাবে। এমনকি চাইলে ডেটাবেজ টেবিলে ডেটা যোগ করতে পারবেন।

php artisan migrate

আপনি চাইলে ফ্রন্টএন্ড থেকে কিভাবে নোট তৈরি, আপডেট এবং ডীলেট করতে হয়, তার জন্য এই লেখা দেখতে পারেন। যদিও এই লেখার জন্য ফ্রন্টেন্ড গুরুত্বপূর্ণ না।

ল্যারাভেলের আগের ভার্সনে ডিফল্ট ভাবে API যুক্ত থাকত। এখন ইন্সটল করতে হয়। তার জন্য নিচের কমান্ড লিখবঃ

php artisan install:api

আমাদেরকে ডেটাবেজ মাইগ্রেট করব কিনা, তা জিজ্ঞেস করবে। yes লিখে ডেটাবেজ মাইগ্রেট করে নিব।

আমরা দেখব routes ফোল্ডারে api.php ফাইল যুক্ত হয়েছে। এখানে আমরা API রুট গুলো লিখতে পারব। যেমন সব গুলো নোটের JSON রেসপন্স পাওয়ার জন্য এভাবে লিখতে পারিঃ

use App\Models\Note;

Route::get('/note', function (Request $request) {
    return Note::all();
});

এখন যদি ব্রাউজারে example.com/api/notes ভিজিট করি, তাহলে ডেটাবেজে থাকা সব গুলো নোট রিটার্ণ করবে। যদি কোন নোট না থাকে তাহলে একটা শূন্য এরে [] রিটার্ণ করবে।

আমরা যেমন Note এর জন্য কন্ট্রোলার তৈরি করে CURD অপারেশন যুক্ত করেছি, ঠিক তেমনি API এর ক্ষেত্রেও একটা কন্ট্রোলার তৈরি করতে পারি।

php artisan make:controller ApiNoteController --api

ফলে ওয়েব রুটের মত এক লাইনেই সব গুলো API রুট পেয়ে যাবোঃ

use App\Http\Controllers\ApiNoteController;

Route::resource('note', ApiNoteController::class);

ApiNoteController.php ফাইলে প্রথমে Note মডেল ইনক্লুড করে নিব use App\Models\Note; ব্যবহার ক্রে।

এরপর index মেথড এভাবে লিখবঃ

    public function index()
    {
        return Note::all();
    }

এখন যদি example.com/api/note ভিজিট করি, তাহলে আগের মতই সব গুলো নোটের JSON রেসপন্স পাবো।

একটা সিঙ্গেল আইটেম এর রেসপন্স পাওয়া

উপরে আমরা সব গুলো নোট রেসপন্স পেয়েছি। চাইলে নোটের আইডি ব্যবহার করে শুধু মাত্র একটা সিঙ্গেল নোটের রেসপন্স পেতে পারি। তার জন্য ApiNoteController.php ফাইলের show মেথড এভাবে লিখবঃ

    public function show(Note $note)
    {
        return $note;
    }

সিঙ্গেল নোট পাবো এভাবে example.com/api/note/1

ডেটাবেজে যদি নোট না থাকে, তাহলে আগে ডেটাবেজে নোট স্টোর করে করে এপর উপরের দুইটা মেথড আমরা চেক করতে পারি।

API ব্যবহার করে নোট নোট তৈরি

ApiNoteController.php ফাইলে store মেথড এভাবে লিখবঃ

    public function store(Request $request)
    {
        $data = $request->validate([
            'title' => 'required',
            'note' => 'required'
        ]);

        $note = Note::create($data);
        return  $note;
    }

নোট তৈরি করার সময় POST রিকোয়েস্টের মাধ্যমে API কল করতে হয়। তার জন্য আমরা Postman ব্যবহার করে দেখতে পারব। Postman ওপেন করে একটা নতুন HTTP রিকোয়েস্ট ট্যাব খুলব। রিকোয়েস্ট টাইপ হিসেবে ডিফল্ট ভাবে GET থাকে। তা পরিবর্তন করে POST সিলেক্ট করব। এড্রেস হবে এমনঃ example.com/api/note

এছাড়া Headers ট্যাব থেকে Accept কি যুক্ত করতে হবে। যার ভ্যালু হবে application/json।

এখন যদি আমরা send বাটনে ক্লিক করি, তাহলে একটা এরর দিবে। মূলত title এবং note ফিল্ড না দেওয়ার কারণে। পোস্টম্যানে Body ট্যাব ওপেন করব।

এখানে রিকোয়েস্ট বডিতে আমরা raw ভ্যালু পাস করব। আর নিচে ভ্যালু ফিল্ডে JSON ডেটা পাস করব। যেমন নিচের ডেটা পাস করে দেখতে পারিঃ

{
    "title" : "This is an awesome note",
    "note" : "This is content of the note."
}

সব কিছু ঠিক থাকলে নোট ডেটাবেজে নোট স্টোর হবে। এবং নিচের মত করে ঐ নোটের ডেটা রিটার্ণ করবেঃ

{
  "id": 3,
  "title": "This is an awesome note",
  "note": "This is content of the note.",
  "created_at": "2024-09-04T07:05:35.000000Z",
  "updated_at": "2024-09-04T07:05:35.000000Z"
}

চাইলে ডেটাবেজ ব্রাউজ করে দেখতে পারি।

নোট আপডেট করা

নোট স্টোর করা এবং আপডেট করা অলমোস্ট একই রকম। তাই আমরা চাইলে store মেথড কপি করতে পারি।

 public function update(Request $request, Note $note)
    {
        $data = $request->validate([
            'title' => 'required',
            'note' => 'required'
        ]);

        $note->update($data);
        return  $note;
    }

আমরা শুধু $note = Note::create($data); এর পরিবর্তে $note->update($data); লিখেছি।

নোট আপডেট করতে হয় PUT রিকোয়েস্টের মাধ্যমে। আমরা চাইলে পোস্টম্যানে নতুন নোট তৈরি করার ট্যাবটি ডুপ্লিকেট করে POST এর পরিবর্তে PUT রিকোয়েস্ট ব্যবহার করতে পারিঃ

নোট আপডেট করার সময় নোটের ID দিতে হবে। তাই আমাদের রিকোয়েস্ট URL হবে এমনঃ example.com/api/note/{id}। এছাড়া পোস্ট রিকোয়েস্টের মত Headers ট্যাব থেকে Accept কি যুক্ত করতে হবে। যার ভ্যালু হবে application/json।

এখন যদি send বাটনে ক্লিক করি, তাহলে নোট আপডেট হবে এবং আমাদের আপডেটেড নোট রিটার্ণ করবে। নির্দিষ্ট নোট না থাকলে এরর দেখাবে।

নোট ডিলেট করা

ডিলিট করা সবচেয়ে সহজ। তার জন্য ApiNoteController.php এর destroy মেথড এভাবে লিখবঃ

    public function destroy(Note $note)
    {
        $note->delete();
        return ['message' => 'The note was deleted'];
    }

পোস্টম্যানে একটা নতুন ট্যাব খুলব। এড্রেস হবে এমন example.com/api/note/{id}। আর মেথড হবে DELETE। এরপর send বাটনে ক্লিক করলেই পোস্ট ডিলিট হয়ে যাবে।

এখানে খেয়াল রাখতে হবে যেন ঐ আইডির নোট থাকে। যদি না থাকে, তাহলে এরর দেখাবে।

অথেনটিকেশন – ল্যারাভেল স্যাংকটাম

উপরের স্টেপ গুলো ফলো করলে আমরা বুঝতে পারব যে যে কেউ চাইলে আমাদের প্রজেক্টের ডেটা এক্সেস করতে পারবে। ডেটা এড করার পাশা পাশি মডিফাই বা ডিলেটও করতে পারবে। এই সমস্যাসা সমাধানের জন্য ল্যারাভেল স্যাংকটাম।

প্রথমে আমরা ইউজার রেজিস্ট্রেশন, লগিন ও লগআউট ফাংশনালিটি নিয়ে কাজ করব। তার জন্য একটা কন্ট্রোলার তৈরি করে নেই। নাম দেই ApiAuthController.php। কমান্ড লাইন থেকে কন্ট্রোলারটি তৈরি করতে লিখিঃ

php artisan make:controller ApiAuthController  

API এর মাধ্যমে ইউজার ম্যানেজমেন্টের জন্য User মডেলে HasApiTokens ব্যবহার করতে হবে। তার জন্য use HasFactory, Notifiable; পরিবর্তন করে লিখবে হবে use HasApiTokens, HasFactory, Notifiable;। এবং HasApiTokens ইনক্লুড করে নিতে হবে। সম্পূর্ণ User মডেল হবে এমনঃ

<?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 Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
    protected $fillable = [
        'name',
        'email',
        'password',
    ];
    protected $hidden = [
        'password',
        'remember_token',
    ];
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
}

API থেকে ইউজার রেজিস্ট্রেশন এবং অথেনটিকেশন

প্রথমে api.php ফাইলে একটা রুট তৈরি করে নেইঃ

Route::post('/register', [ApiAuthController::class, 'register']);

ApiAuthController.php ফাইলে register মেথড যোগ করি। এই রুট হচ্ছে একটা POST রিকোয়েস্টের রুট। সব কিছু ঠিক মত কাজ করছে কিনা, তার জন্য register মেথড থেকে সিম্পল একটা স্ট্রিং রিটার্ণ করিঃ

    public function register(Request $request){
    return "register";
}

পোস্টম্যানে গিয়ে একটা পোস্ট রিকোয়েস্ট করি example.com/api/register এড্রেসে।

Headers ট্যাব থেকে Accept কি যুক্ত করতে হবে। যার ভ্যালু হবে application/json। তা না হলে এরর দেখাবে। যদি register স্ট্রিং রিটার্ণ পাই, তাহলে বুঝতে পারব সব সুন্দর মত কাজ করছে। এবার register মেথড এভাবে লিখিঃ

    public function register(Request $request){
      $data = $request->validate([
        'name'=> 'required|max:255',
        'email'=> 'required|email|unique:users',
        'password' => 'required'
      ]);
    $user =  User::create($data);
    $token = $user->createToken($request->name);
    return [
        'user' => $user,
        'token' => $token->plainTextToken
    ];
    }

এখানে শুরুতে আমরা রিকোয়েস্ট ডেটা গুলো ভ্যালিডেট করে নিয়েছি। এরপর ঐ ভ্যালিডেটেড ডেটা ব্যবহার করে নতুন ইউজার তৈরি করেছি। এবং সদ্য তৈরি করা ইউজারকে একটা ভ্যারিয়েবলে রেখেছিঃ $user = User::create($data);

ওয়েব অ্যাপলিকেশনে ইউজার রেজিস্ট্রেশন এবং লগিন করার পর তা সেশনের মাধ্যমে ম্যানেজ করা হয়। সেশন থেকে আমরা বুঝতে পারি ইউজার লগিন করা অবস্থায় আছে কিনা। API তে তো আর সেশন নেই। আর এর বিকল্প হচ্ছে টোকেন। টোকেন দিয়ে বুঝতে পারি একটা ইউজার লগিন করা অবস্থায় রয়েছে কিনা। আর এই টোকেন ম্যানেজ করে ল্যারাভেল স্যাংক্টাম। ইজারকে একটা টোকেন জেনারেট করে দেয়। আর একটা টোকেন হ্যাস করে ডেটাবেজে সেভ করে রাখে। টোকেন তৈরি করার জন্য আমরা লিখেছি $token = $user->createToken($request->name);।

পরবর্তীতে এই ইউজার ইনফরমেশন এবং টোকেন রেসপন্স হিসেবে রিটার্ণ করেছি।

এবার example.com/api/register এন্ডপয়েন্টে আমরা পোস্ট রিকোয়েস্ট করব। Body ট্যাব থেকে raw ভ্যালু হিসেবে name, email এবং password দিতে হবেঃ

{
    "name" : "Umar",
    "email" : "[email protected]",
    "password" : "12345"
}

এরপর যদি পোস্টম্যানে রিকোয়েস্ট করি, তাহলে নিচের মত রেসপন্স পাবোঃ

{
    "user": {
        "name": "Umar",
        "email": "[email protected]",
        "updated_at": "2024-09-05T04:33:36.000000Z",
        "created_at": "2024-09-05T04:33:36.000000Z",
        "id": 4
    },
    "token": "11|UuIBnswlr6PN0sdqFtXSh544w5KYiSQcLf9lbpVRa8d35b58"
}

সাধারণত যে অ্যাপ থেকে API কল করব, সেখানে এই টোকেন ব্যবহার করে বুঝতে পারব যে ইউজার লগিন অবস্থায় রয়েছে।

ইউজার লগিন

ইউজার লগিনের জন্য প্রথমে api.php ফাইলে নতুন আরেকটা রুট যোগ করবঃ

Route::post('/login', [ApiAuthController::class, 'login']);

এবার ApiAuthController.php ক্লাসে login মেথড এভাবে লিখবঃ

     public function login(Request $request){
        $request->validate([
            'email' => 'required|email',
            'password' => 'required|string',
        ]);

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

          if (!$user || !Hash::check($request->password, $user->password)) {
            return [
                'message' => 'The provided credentials are incorrect.'
            ];
          }
          $token = $user->createToken($user->name);
          return [
              'user' => $user,
              'token' => $token->plainTextToken
          ];

    }

পাসওয়ার্ড যেহেতু ডেটাবেজে হ্যাস করে রাখে। তাই কম্পেয়ার করার সময় হ্যাস ভ্যালু কম্পেয়ার করেছি। আর এই জন্য use Illuminate\Support\Facades\Hash; হ্যাস ফ্যাসাদ ইনক্লুড করে নিতে হবে।

এখানে প্রথমে রিকোয়েস্ট বডি থেকে ডেটা ভ্যালিডেট করে নিয়েছি। এরপর ঐ ইমেইল দিয়ে কোন ইউজার আছে কিনা, তা দেখেছি। এবং চেক করেছি যে পাসওয়ার্ড দিয়েছে, তা ডেটাবেজে থাকা পাসওয়ার্ডের সাথে মিলে কিনা। যদি না মিলে তাহলে The provided credentials are incorrect. এই ইরর দেখাবে। আর যদি ইউজার পাওয়া যায় এবং পাসওয়ার্ড মিলে, তাহলে ইউজার এবং টোকেন রিটার্ণ করেছি রেসপন্স হিসেবে।

পোস্টম্যানে রেজিস্ট্রেশনের মত আরেকটা POST রিকোয়েস্ট করি যার এড্রেস হবে এমন example.com/api/login। রিকোয়েস্ট বডিতে শুধু ইমেইল এবং পাসওয়ার্ড ইনপুট দিবঃ

{
    "email" : "[email protected]",
    "password" : "12345"
}

যদি সব ঠিক থাকে, তাহলে এররকম রেসপন্স পাবোঃ

{
    "user": {
        "id": 4,
        "name": "Umar",
        "email": "[email protected]",
        "email_verified_at": null,
        "created_at": "2024-09-05T04:33:36.000000Z",
        "updated_at": "2024-09-05T04:33:36.000000Z"
    },
    "token": "12|x07fUOQWEz4IuOpc5h3D7KxJOSENoxMEaHjyunki8aba2796"
}

যে কোন একটা কিছু ভুল করে দেখুন। দেখবেন রেসপন্স হিসেবে এরর আসছে।

ইউজার লগআউট

লগআউট করা মানে হচ্ছে ডেটাবেজ থেকে টোকেন গুলো ডিলিট করা।

আমরা যদি ডেটাবেজ খুলে দেখি, তাহলে দেখব personal_access_tokens টেবিলে token গুলো সেভ করা থাকে। একটা ইউজার যতবার লগিন করবে, ততবার এই টোকেন গুলো সেভ হবে। আর লগআউট করলে সব গুলো টোকেন রিমুভ হয়ে যাবে।

লগআউট রুট

আমরা লগআউট তখনি করতে পারব, যখন একজন ইউজার লগিন অবস্থায় থাকবে, তাই না? আর এই জন্য লগআউট রুটে স্যাংকটাম মিডেলওয়ার যোগ করতে হবে। যা নিশ্চিত করবে যে ইউজার লগিন অবস্থায় রয়েছে কিনা। তার জন্য api.php ফাইলে logout রুট এভাবে লিখবঃ

Route::post('/logout', [ApiAuthController::class, 'logout'])->middleware('auth:sanctum');;

ApiAuthController.php ক্লাসে logout মেথড এভাবে লিখিঃ

    public function logout(Request $request){
        $request->user()->tokens()->delete();
         return ['message' => 'User logged out successfully'];
    }

এখানে টোকেন ডিলিট করার পর রেসপন্স হিসেবে একটা মেসেজ রিটার্ণ করেছি।

পোস্টম্যানে লগআউট টেস্ট করাঃ

পোস্টম্যানে example.com/api/logout এন্ডপয়েন্টে একটা পোস্ট রিকোয়েস্ট করব। Headers ট্যাব থেকে Accept কি যুক্ত করব যার ভ্যালু হবে application/json। এরপর যদি Send বাটনে ক্লিক করি, তাহলে নিচের এরর পাবোঃ

{
    "message": "Unauthenticated."
}

মানে অথেনটিকেশন এরর। এর কারণ হচ্ছে কোন ইউজারকে লগআউট করবে, তা আমরা বলে দেইনি। আমরা যখন রেজিস্ট্রেশন বা লগিন করেছি, তখন একটা টোকেন পেয়েছি। ঐ টোকেন দিয়ে বলে দিতে পারব যে কোন ইউজার লগআউট করবে।

Auth ট্যাব থেকে Auth Type হিসেবে Bearer Token সিলেক্ট করব। এরপর Token হিসেবে লগইন করার পর যে টোকেন পেয়েছি, ঐ টোকেন দিব। এবং এরপর যদি Send বাটনে ক্লিক করি, তাহলে ইউজার লগআউট হয়ে যাবে। এই মুহুর্তে যদি ডেটাবেজে যাই, দেখব ঐ নির্দিষ্ট ইউজারের সব গুলো টোকেন ডিলিট হয়ে গিয়েছে।

ডেটা প্রটেক্ট করা

আমরা দেখেছি যে কেউই নোট এড করতে পারে, নোট এডিট অথবা ডিলিট করতে পারে। আমরা যেহেতু ইউজার অথেনটিকেশনের কাজ করেছি, এবার নোট গুলোকে প্রটেক্ট করতে পারব।

এর আগে ল্যারাভেলে ইউজার এবং অথেনটিকেশন – প্রাইভেট নোট অ্যাপ লেখায় দেখেছি কিভাবে ওয়েব ভার্সনে ডেটা প্রটেক্ট করা যায়। এখনো প্রায় সিমিলার স্টেপ আমাদের নিতে হবে।

ইউজারের আন্ডারে নোট সেভ করা

একটা নোট কোন ইউজার তৈরি করেছে, তা নোট টেবিলে স্টোর করতে হবে। তার জন্য নতুন একটা কলাম তৈরি করতে হবে note টেবিলে। …create_note_table.php মাইগ্রেশন ফাইলে ইউজার আইডি কলাম যোগ করিঃ $table->foreignId('user_id')->constrained()->onDelete('cascade');

সম্পূর্ণ up মেথড হবে এমনঃ

    public function up(): void
    {
        Schema::create('notes', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->string('title');
            $table->longText('note');
            $table->timestamps();
        });
    }

এরপর ডেটাবেজ মাইগ্রেট করে নিবঃ

php artisan migrate:refresh

ফলে ডেটাবেজের note টেবিল user_id কলাম যোগ হবে। এখানে constrained()->onDelete(‘cascade’) এর মানে হচ্ছে যদি নির্দিষ্ট ইউজার ডিলিট হয়ে যায়, তাহলে তার সকল নোট ডিলিট হয়ে যাবে।

রিলেশনশিপ সেট করা

একজন ইউজারের আন্ডারে একাধিক নোট থাকতে পারে। App>Models> User.php মডেলে নিচের মেথড যোগ করি। class User extends Authenticatable {…} এর ভেতর যে কোন এক জায়গায় যোগ করলেই হবে।

public function notes()
   {
       return $this->hasMany(Note::class);
   }

একটা নোট শুধু মাত্র একজন ইউজারের আন্ডারে থাকবে। তাই App>Models> Note.php মডেলে নিচের মেথড যোগ করিঃ

public function user()
{
    return $this->belongsTo(User::class);
}

সম্পূর্ণ Note.php ফাইলঃ

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Note extends Model
{
    use HasFactory;
    protected $fillable = ['title', 'note'];
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

ইউজারের আন্ডারে নোট সেভ করাঃ

এর আগে আমরা সরাসরি নোট ডেটাবেজে যোগ করেছি। এবার একজন ইউজারের আন্ডারে নোট যোগ করব। আর তার জন্য আমাদের ApiNoteController.php ফাইলের store মেথড এভাবে লিখতে হবেঃ

    public function store(Request $request)
    {
        $data = $request->validate([
            'title' => 'required',
            'note' => 'required'
        ]);

        $note = $request->user()->notes()->create($data);
        return ['note' => $note];
    }

এর আগে নোট স্টোর করেছি এভাবেঃ $note = Note::create($data);

এখন আগে আমরা ইউজার অথেনটিকেটেড তা দেখে নিচ্ছি প্রথমে। এরপর নোট স্টোর করছিঃ $note = $request->user()->posts()->create($data);

রুটে অথেনটিকেশন মিডেলওয়ার যোগ করাঃ

লগিন ইউজার ছাড়া কেউ যেন নোট এপিআই রুট গুলো এক্সেস করতে না পারে, তার জন্য api.php ফাইলে স্যাংকটাম মিডেলওয়ার যোগ করতে হবে। Route::resource('note', ApiNoteController::class) রুটে middleware('auth:sanctum') যোগ করলেই হবেঃ

Route::resource('note', ApiNoteController::class)->middleware('auth:sanctum');

এখন যদি পোস্টম্যানে আমরা নোট তৈরি করার রিকোয়েস্ট করি, তাহলে নিচের মত এরর পাবোঃ

{
    "message": "Unauthenticated."
}

এর কারণ হচ্ছে আমরা কোন ইউজার টোকেন প্রোভাইড করিনি।

ফ্রেশ মাইগ্রেশনের কারণে আমাদের ডেটাবেজের সকল ইউজার ডিলেট হয়ে গিয়েছে। পোস্টম্যানে রিকোয়েস্ট করে আমরা নতুন একটা ইউজার তৈরি করে নিব। রিটার্ণ হিসেবে ইউজারের পাশাপশি আমরা একটা টোকেন পাবো। ঐ টোকেন কপি করে নিব। এরপর পোস্ট তৈরির রিকোয়েস্ট করার সময় Auth ট্যাব থেকে Auth Type থেকে Bearer Token সিলেক্ট করব। এবং Token ফিল্ডে কপি করা টোকেন দিয়ে রিকোয়েস্ট করব। তাহলে দেখব নোট ডেটাবেজে সেভ হয়েছেঃ

{
    "note": {
        "title": "Awesome note",
        "note": "This is content of the note.",
        "user_id": 1,
        "updated_at": "2024-09-05T05:53:39.000000Z",
        "created_at": "2024-09-05T05:53:39.000000Z",
        "id": 1
    }
}

নোট আপডেট

বর্তমানে নোট আপডেট করার কোড এমনঃ

    public function update(Request $request, Note $note)
    {
        $data = $request->validate([
            'title' => 'required',
            'note' => 'required'
        ]);

        $note->update($data);
        return  $note;
    }

আমরা চাইলে API কল করে নোট আপডেট করতে পারব। সমস্যা হচ্ছে এক ইউজারের নোট অন্য ইউজার আপডেট করতে পারবে। এর জন্য প্রথমে অথোরাইজেশন চেক করে নিবঃ

     if (Auth::id() !== $note->user_id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

এর জন্য Auth ফ্যাসাদ ইনক্লুড করে নিতে হবেঃ

use Illuminate\Support\Facades\Auth;

তাহলে update মেথড হবে এমনঃ

    public function update(Request $request, Note $note)
    {
        if (Auth::id() !== $note->user_id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }
        $data = $request->validate([
            'title' => 'required',
            'note' => 'required'
        ]);
        $note->update($data);
        return  $note;
    }

এখন আমরা চাইলেও অন্য ইউজারের টোকেন ব্যবহার করে নোট আপডেট করতে পারব না।

নোট ডিলিট

এক ইউজার যেন অন্য ইউজারের নোট ডিলিট করতে না পারে, তার জন্য destroy মেথড এভাবে লিখবঃ

    public function destroy(Note $note)
    {
        if (Auth::id() !== $note->user_id) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }
        $note->delete();
        return ['message' => 'The note was deleted'];
    }

উপরে নোটের ওনার চেক করার যে পদ্ধতি অনুসরণ করেছি, তা হচ্ছে ডাইরেক্ট অথোরাইজেশন। আরেকটা পদ্ধতি হচ্ছে পলিসি বেইজড। ইনশাহ আল্লাহ ফিউচারে কোন লেখায় তা নিয়ে লিখব।

এই লেখায় আমরা ল্যারাভেল নিয়ে অনেক কিছু শিখতে পেরেছি, তাই না? প্রজেক্ট কোড গিটহাবে পাওয়া যাবে। এছাড়া ল্যারাভেল নিয়ে অন্যান্য লেখা গুলো পাওয়া যাবে বাংলায় ল্যারাভেল টিউটোরিয়াল পেইজে।

3 thoughts on “ল্যারাভেলে REST API তৈরি এবং অথেনটিকেশন”

Leave a Reply