هادی محمدزاده
3 سال پیش توسط هادی محمدزاده مطرح شد
8 پاسخ

باگ بسیار وحشتناک در laravel passport

سلام و وقت بخیر
من دو تا guard توی پروژه خودم دارم. api و admin.
هر دوی ای گارد ها با درایور laravel passport کانفیگ شدن. اسم جداول هم فرق میکنه . جداول من اینهاست : users و admins

حالا یه اتفاق خیلی وحشتناک افتاده!
اگر یک کاربر معمولی با ایدی 1 توی سیستم لاگین کنه و اکسس تاکن بگیره میتونه به حساب کاربری ادمین شماره 1 دسترسی داشته باشه ! و به همین شکل کاربر شماره 2 میتونه به حساب کاربری ادمین شماره 2 !!!!!
این موضوع خیلی وحشتناکه و من بارها سرچ کردم و هیچ چیزی توی نت در موردش پیدا نکردم!
ممنون میشم اگه بررسی داشته باشید و راهنماییم کنید

محتوای فایل config/auth.php :

'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],

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

        'admin' => [
            'driver' => 'passport',
            'provider' => 'admins',
            'hash' => false,
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class,
        ]
    ],

وقتی کاربر (گارد api) کد ملی و کد فعال سازیشو وارد میکنه من میام و یه اکسس تاکن برای کاربر میسازم :

$accessToken = $user->createToken('User login')->accessToken;

و این اکسس تاکن رو توی ریسپانس به کاربر برمیگردونم .

وقتی هم ادمین با نام کاربری و پسورد لاگین میکنه به همین شکل کار میکنم :

$username = $this->request->get('username');
        $password = $this->request->get('password');
        if (! $admin = AdminRepository::getInstance()->checkUsernameAndPassword($username, $password))
            throw new InvalidAuthAdminException();

        $accessToken = $admin->createToken('admin')->accessToken;

توی فایل routes/api.php هم دسترسی به روت ها رو اینطوری چک میکنم :

Route::group(['middleware' => ['auth:api']], function() {}(;

Route::group(['middleware' => ['auth:admin']], function() {}(;

الان در صورتی که کاربر با هر کدوم از گارد ها آتنتیکیت کرده باشه چنانچه توی هر دو جدول (جدول کاربران و ادمین ها) آیدیش موجود باشه هر دو کد زیر true برگردونده میشن!!!!

Auth::guard('api')->check()
Auth::guard('admin')->check()

من این موضوع رو توی پروژه های زیادی چک کردم و همه این باگ وحشتناک رو دارن و ظاهرا خیلی از برنامه نویسها ازین موضوع بی خبر هستن.
ممنون میشم یه نفر راهنمایی کنه.
من توی این پروژه از scopes استفاده نکردم


ثبت پرسش جدید
mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 3 سال پیش مطرح شد
0

این باگ passport نیست. استفاده غیر اصولی شما باعث ایجاد این باگ شده. داکیومنت های پکیج رو یکبار دیگه از اول همشو بخونید.


هادی محمدزاده
@hadi.mohammadzade 3 سال پیش مطرح شد
0

@khanzadimahdi من بارها خوندم ولی متوجه نشدم . میشه توضیح بدید مشکل کجاست؟


هادی محمدزاده
@hadi.mohammadzade 3 سال پیش مطرح شد
0

@khanzadimahdi توی داکیومنت لاراول اینرو گفته منم همین کارو کردم
https://laravel.com/docs/8.x/passport#multiple-authentication-guards

کار دیگه ای هم باید انجام میدادم؟


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 3 سال پیش مطرح شد
1

پکیج یه table داره که اونجا access token ها رو ذخیره میکنه و همونجا یه user_id هم درج میشه! حالا شما میای اونو morph میکنی به چندتا جدول درصورتی که اصلا relation که براش درنظر گرفته میشه morph نیست.

https://github.com/laravel/passport/blob/10.x/database/migrations/2016_06_01_000002_create_oauth_access_tokens_table.php

اگه دقت کنی براش فقط id مهمه و اینکه با کدوم نوع از User (که قطعا جدول های متفاوت براش ساختین) ارتباط داره اهمیت نمیده

حالا فرض کن سه تا table داری واسه 3 نوع یوزری که استفاده کردی! همشون هم id = 1 رو دارن! خب حالا اگه بین access_tokens و اون جدول مورد نظرت join بزنیم صرف نظر از اینکه نوع User مهم باشه میره یه ایدی 1 پیدا میکنه میگیره میاره بیرون و لاگین میکنه.


هادی محمدزاده
@hadi.mohammadzade 3 سال پیش مطرح شد
0

@khanzadimahdi بله مشکل دقیقا همینه .
میشه بگید چطوری باید حلش کنم؟


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 3 سال پیش مطرح شد
1

توی داکیومنت راجب گارد های مختلف گفته و مدل های مختلف واسه یوزر! راجب اینکه جدول های متفاوت استفاده کنید چیزی نگفته!

شما اگه میخوای از پاسپورت استفاده کنی باید همه یوزر ها رو توی یه table ذخیره کنی یا اینکه relation های پاسپورت رو دستکاری کنی و کاستوم کنی بر اساس نیازت.


هادی محمدزاده
@hadi.mohammadzade 3 سال پیش مطرح شد
1

@khanzadimahdi این مشکل رو من توی دو سه تا پروژه ی دیگه که دوستتان دیگه نوشته بودن دیدم! خیلی خیلی وحشتناکه این موضوع!
و خب وقتی لاراول ادعا میکنه که پکیج پاسپورت از multiple guard پشتیبانی میکنه و وقتی توی فایل کانفیگ ما ذکر میکنیم که مثلا گارد admin اسم جدولش اینه ، پس این موضوع یه باگ از سمت لاراول هست که احتمالا توی پروزه های بیشماری مخفی مونده !


علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 3 سال پیش مطرح شد
0

اکثرا در زمان شروع یک پروژه، جدا کردن جدول کاربرهای مختلف (ادمین، اپراتور و کاربر عادی) ایده خوب و جذابی به نظر میرسه
اما با بزرگ تر شدن پروژه ، پیچیدگی هایی هم به وجود میاد

سوای پیچیدگی ها، از این جهت بهش فکر کن که
ادمین هم یک کاربره که باید همون اطلاعات کاربر عادی براش ذخیره بشه
تنها چیزی که اضافه داره سطح دسترسی هاش به سیستم هست
که میتونی با یه سیستم Role/Permission مدیریتش کنی
حتی میتونی یه سیستم سطح دسترسی ساده برای خودت بنویسی

منظورم این نیست که این راه ، تنها راه درسته
اما برای ۹۵٪ پروژه ها منطقی ترین روش ممکن هست


یه راهکاری که هست اینه که شما تمام کاربرا رو توی ۱ جدول ذخیره کنی
و بعد اگر خواستی چند تا گارد هم داشته باشی، مشکلی نیست
تمام گاردها باز هم میتونند از یه جدول استفاده کنند
به این ترتیب ID ها یونیک هستند و مشکلی که اشاره کردی، پیش نمیاد


درباره این موضوع هم، که این ماجرا باگ هست یا ویژگی که شاید شما ازش بی خبری
میتونی توی بخش issue های لاراول در گیت‌هاب موضوع رو عنوان کنی و کدهای ReProduce کردن این حالت رو هم منتشر کنی

اگر باگ باشه حتما برطرف میشه
اگر هم مشکل در نوع استفاده از Passport باشه، که عنوان میشه

حتی اگر راهکاری برای حل این موضوع سراغ داری میتونی کدش رو بنویسی و Pull Request بزنی


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام