لارافيل, Api / 2024-09-16

التعامل مع Api في لارافيل - الجزء الثالث - تسجيل الدخول وحماية route بإستخدام Laravel Sanctum.

التعامل مع Api في لارافيل - الجزء الثالث - تسجيل الدخول وحماية route بإستخدام Laravel Sanctum.

2024-09-16 وقت القراءه : 8 دقائق

جدول المحتويات


واحدة من أفضل أنظمة المصادقة التي يوفرها إطار العمل لارافيل، هي Laravel Sanctum حيث يوفر نظام مصادقة سريع لتطبيقات الويب SPA، وتطبيقات الهوات، وواجهات APIs، كما يسمح لكل مستخدم بإنشاء رموز API متعددة لحسابهم.

بعد تسجيل مستخدم أو القيام بعملية تسجيل الدخول، سوف يحصل المستخدم على token وفي كل طلب يتم إرسالة يجب أن يتم إرسال token حتى تتم عملية المصادقة.

في هذه المقالة سوف سيتم شرح كيفية إستخدام Laravel Sanctum في عملية المصادقة، خطوة بخطوة:-

Step 1: setup database in .env file

إعداد ملف .env للإتصال بقاعدة البيانات.

DB_DATABASE=youtube
DB_USERNAME=root
DB_PASSWORD= redhat@123


Step 2:Install Laravel Sanctum.

تثبيت حزمة Laravel Sanctum

composer require laravel/sanctum


Step 3:Publish the Sanctum configuration and migration files .

عمل publish لإعدادات حزمة Sanctum وملف migration

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"


Step 4:Run your database migrations.

تنفيذ ملف migration لتهيئة حقل users للتعامل مع laravel Sanctum.

php artisan migrate

بعد عمل migrate سيتم إنشاء جدول جديد بإسم personal_access_tokens


Step 5:Add the Sanctum's middleware.

إضافة Sanctum Middleware

حيث نذهب للملف kernel.php وبداخل الدالة middlewaregroup ونعدل على api بالشكل التالي

../app/Http/Kernel.php
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
...
    protected $middlewareGroups = [
        ...
        'api' => [
            EnsureFrontendRequestsAreStateful::class,
            'throttle:60,1',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];
    ...
],


Step 6:To use tokens for users.

لإستخدام sanctum tokens للـ User Model يجب إخبار UserModel بإستخدام HasApiTokens

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

 بذلك نكون قد إنتهينا من إعدادات Sanctum


Step 7:Let's create the seeder for the User model

إنشاء Seeder للـ User Model

php artisan make:seeder UsersTableSeeder


Step 8:Now let's insert as record

لإدخال البيانات في جدول Users بإستخدام UserTableSeeder نذهب للملف UserTableSeeder الموجود في المسار 

database/seeders/UserTableSeeder.php

وبداخل الدالة run نضيف جمل الإدخال

class UsersTableSeeder extends Seeder
{
    public function run()
    {
        DB::table('users')->insert([
            'name' => 'John Doe',
            'email' => 'john@doe.com',
            'password' => Hash::make('password')
        ]);
    }
}


Step 9:To seed users table with user

ولعمل seed من خلال artisan

php artisan db:seed --class=UsersTableSeeder


Step 10: create a controller nad /login route in the routes/api.php file:

إضافة route في ملف api.php

Route::post('login',[UserController::class,'index']);

وللتحقق وتسجيل الدخول من خل دالة login بداخل الكلاس UserController

namespace App\Http\Controllers;

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

class UserController extends Controller
{
    function login(Request $request)
    {
        $user= User::where('email', $request->email)->first();
        // print_r($data);
        if (!$user || !Hash::check($request->password, $user->password)) {
            return response([
                'message' => ['These credentials do not match our records.']
            ], 404);
        }

        $token = $user->createToken('my-app-token')->plainTextToken;

        $response = [
            'user' => $user,
            'token' => $token
        ];

        return response($response, 201);
    }

حيث إنه سيتحقق إذا إذا كان البريد الإلكتروني مسجل في قاعدة البيانات، ومن ثم سيتحقق من password، إذا كانت غير متوافقة سيتم إرجاع خطأ 404 ورسالة 'These credentials do not match our records. 

أما إذا كانت البيانات صحيحة فإنه سيتم إرجاع المستخدم مع token والكود سيكون 201.

مع الإنتباه هنا أنه عندما تم إنشاء token تم وضع إسم لهذا token وهو my_app_token وهو إسم بمثابة key نستطيع إختيار أي إسم نريد فليس شرط أن يكون my_app_token.


Step 11: Test with postman, Result will be below

لفحص تسجيل الدخول بإستخدام postman.

كما نلاحظ أنه تم إرجاع user وكذلك token.


Step 12: Make Details API or any other with secure route

لحماية route في ملف api.php والتأكد من أن المستخدم قام بتسجيل الدخول، يجب إضافة middleware=>auth:sanctum 

Route::group(['middleware' => 'auth:sanctum'], function(){
    //All secure URL's
    });

Route::post("login",[UserController::class,'index']);


على سبيل المثال لو كان لدي route بالشكل التالي 

Route::apiResource('brands',BrandController::class);


وأريد أن لا يتم عرض / تعديل / تخزين / حذف الـ brands إلا للمستخدمين الذين قاموا بتسجيل الدخول، يجب وضع هذا route بداخل middleware=>auth:sanctum

Route::group(['middleware' => 'auth:sanctum'], function(){
    Route::apiResource('brands',BrandController::class);
});
Route::post("login",[UserController::class,'index']);

الأن لو حاولنا زيارة الرابط http://www.test.test/api/brands لعرض المنتجات فإننا سوف نحصل على خطأ لأنه يجب إرسال token مع كل request تم حمايته بإستخدام middleware=>auth:sanctum

ولإرسال token من خلال postman نذهب للتبويب headers ويجب إضافة 

Authorization : Bearer 2|8r16cVhcsI2DyPGogVDKmSKD2g4xEBTcsi5XHQAu

حيث يجب إضافة Bearer ومن ثم token الذي تم تسجيل الدخول من خلاله.

كما نلاحظ أنه تم عرض brands بنجاح.


أما إذا كنت لا ترغب في كتابة كلمة Bearer فبالإمكان إختيار نوع Auth بأن يكون Bearer Token وكتابة token كما بالصورة أدناه.


Step 13: Register New User

تسجيل مستخدم جديد

بداية لتسجيل مستخدم جديد يجب إنشاء كلاس للتحقق من المدخلات، وذلك من خلال إنشاء UserRegisterRequest

class UserReqisterRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name'=>'required|string',
            'email'=>'required|string|unique:users,email',
            'password'=>'required|string|confirmed',
        ];
    }
}


وفي دالة store بداخل UserController سيتم تسجيل المستخدم 

public function register(UserReqisterRequest $request){
    $user=new User();
    $user->name=$request->name;
    $user->email=$request->email;
    $user->password=Hash::make($request->password);
    $user->save();
    $token=$user->createToken('my-app-token')->plainTextToken;
    $respons=[
        'user'=>$user,
        'token'=>$token
    ];
    return $respons;
}

ولإرسال البيانات من خلال postman


Step 14: Logout

خطوات تسجيل الخروج:-

إنشاء route لتسجيل الخروج

Route::group(['middleware' => 'auth:sanctum'], function(){
    Route::apiResource('brands',BrandController::class);
    Route::post('logout',[UserController::class,'logout']);
});


إنشاء دالة logout بداخل UserController

public function logout(Request $request){
    auth()->user()->tokens()->delete();
}

الحذف من خلال postman

حيث يجب إرسال token الخاص بالمستخدم الذي سيتم عمل تسجيل خروج له.

حيث سيتم حذف token التابع للمستخدم الذي تم إرسال token له من جدول personal_access_tokens.


Step 15: Permissions

توفر لنا Sanctum التحكم بالصلاحيات، حيث يتم ذلك من خلال إضافة مصفوفة بالصلاحيات إلى token، على سبيل المثال لإضافة صلاحية brand-list، ومن لديه هذه الصلاحية يستطيع عرض brands

إضافة الصلاحية بإسم brand-list

$token=$user->createToken('my-app-token',['brand-list'])->plainTextToken

وللتحقق من الصلاحية، نذهب لدالة عرض brand في brandController ونستخدم tokenCan

public function index()
{
     if(!auth()->user()->tokenCan('brand-list')){
        abort(403,'UnAuthorized');
    }
    return Brand::get();
}

التعليقات
واثق الشويطر
منذ 3 سنوات

مقالات جميلة .. شكرا لك..

زائر
منذ 3 سنوات

اين يتم إضافة هذا الكود $token=$user->createToken(\'my-app-token\',[\'brand-list\'])->plainTextToken;

حبيب
منذ 3 سنوات

شككرا على مجهودك لو سمحت لدي استفسار مالفرق بين Sanctum و passport ومتى نستخدم هذه أو تلك؟

ابراهيم حسن
منذ 3 سنوات

بستفيد جددا من مقالات حضرتك الله يحفظك يارب , ويتريت تستمر ♥

خالد حسن
منذ سنتين

مقال رهيب، شكرا يا ايثار ❤️

خالد حسن
منذ سنتين

مقال رهيب، شكرا يا ايثار ❤️

إضافة تعليق
Loading...