احراز هویت کاربران در PHP با سیمفونی (Symfony) – راهنمای کاربردی


در این مقاله با روش راهاندازی احراز هویت کاربران در PHP با استفاده از کامپوننت امنیت سیمفونی آشنا خواهیم شد. سیمفونی یک فریمورک PHP برای توسعه وب با عملکرد بالا است. در این مقاله علاوه بر روش احراز هویت، با چگونگی مجوزدهی مبتنی بر نقش نیز آشنا میشویم که در عمل میتوانید بر اساس نیازهای خود آن را بسط دهید.
کامپوننت امنیت سیمفونی
کامپوننت امنیت سیمفونی امکان راهاندازی برخی امکانات امنیتی مانند احراز هویت، مجوزدهی مبتنی بر نقش، توکنهای CSRF و موارد دیگر را به آسانی فراهم میسازد. در واقع این کامپوننت، خود به چهار کامپوننت فرعی تقسیم میشود که میتوانید بر حسب نیاز از هر کدام آنها استفاده کنید.
کامپوننت امنیت چهار کامپوننت فرعی زیر را دارد:
- symfony/security-core
- symfony/security-http
- symfony/security-csrf
- symfony/security-ac
در این مقاله، قصد داریم به بررسی امکان احراز هویت ارائه شده از سوی کامپوننت symfony/security-core بپردازیم. به طور معمول کار خود را با دستورالعملهای نصب و پیکربندی آغاز میکنیم و سپس به بررسی نمونههای عملی از این کامپوننت، جهت نمایش مفاهیم کلیدی ادامه میدهیم.
نصب و پیکربندی
در این بخش قصد داریم کامپوننت امنیت سیمفونی را نصب کنیم. ما تصور میکنیم که شما قبلاً Composer را روی سیستم خود نصب کردهاید، چون آن را برای نصب کامپوننت امنیت که در Packagist قرار دارد نیاز داریم.
بنابراین پیشتر میرویم و کامپوننت امنیت را با استفاده از دستور زیر نصب میکنیم:
$composer require symfony/security
ما قصد داریم کاربران را از پایگاه داده MySQL در مثال خود بارگذاری کنیم و از این رو باید یک لایه انتزاع برای پایگاه داده داشته باشیم. بنابراین در ادامه یکی از محبوبترین لایههای انتزاع پایگاه داده یعنی Doctrine DBAL را نصب میکنیم:
$composer require doctrine/dbal
بدین ترتیب فایلی به نام composer.json ایجاد میشود که مانند زیر است:
در ادامه اقدام به تغییر دادن فایل composer.json میکنیم تا به حالت زیر دربیاید:
از آنجا که اینک مدخل classmap را اضافه کردهایم، میتوانیم بارگذار خودکار کامپوزر را با اجرای دستور زیر بهروزرسانی کنیم:
$composer dump -o
اینک میتوانیم از فضای نام sfauth برای بارگذاری خودکار کلاسهای موجود در دایرکتوری src استفاده کنیم.
بدین ترتیب بخش نصب به پایان میرسد. برای استفاده از این کامپوننت کافی است که فایل autoload.php ایجاد شده از سوی کامپوزر که در اپلیکیشن خود ایجاد کردهایم را به صورتی که در قطعه کد زیر میبینید include کنیم:
مثالی از دنیای واقعی
در ابتدا به بررسی گردش کار احراز هویت معمول ارائه شده از سوی کامپوننت امنیت سیمفونی میپردازیم.
- نخستین کاری که باید انجام داد، بازنویسی اطلاعات امنیتی کاربر و ایجاد یک توکن غیر احراز شده است.
- سپس یک توکن احراز نشده را به بخش مدیریت احراز هویت میفرستیم تا اعتبارسنجی شود.
- مدیریت احراز هویت میتواند شامل ارائهدهندگان مختلف احراز هویت باشد و یکی از آنها برای احراز هویت درخواست کاربر جاری استفاده میشود. منطق چگونگی احراز هویت کاربر در «ارائهدهنده احراز هویت» (Authnication Provider) تعریف شده است.
- ارائهدهنده احراز هویت با ارائهدهنده کاربر تماس میگیرد و کاربر را بازیابی میکند. بارگذاری کاربران از بکاند مربوطه در حوزه وظایف بخش ارائهدهنده کاربر است.
- بخش ارائهدهنده کاربر تلاش میکند که کاربر را با استفاده از اطلاعات ارائه شده از سوی ارائهدهنده احراز هویت بارگذاری کند. در اغلب موارد ارائهدهنده کاربر، شیء کاربر را که به پیادهسازی رابط UserInterface میپردازد بازگشت میدهد.
- اگر کاربر پیدا شود، ارائهدهنده احراز هویت یک توکن احراز نشده بازگشت میدهد و میتوانید این توکن را برای درخواستهای بعدی ذخیره کنید.
در این مثال ما قصد داریم اطلاعات کاربر را با پایگاه داده MySQL مقایسه کنیم و از این رو باید یک پایگاه داده ارائهدهنده کاربر را ایجاد کنیم. همچنین باید پایگاه داده ارائهدهنده احراز هویت را نیز ایجاد کنیم تا بتواند منطق احراز هویت را مدیریت کند. در نهایت کلاس «کاربر» (User) را ایجاد میکنیم که به پیادهسازی رابط UserInterface میپردازد.
کلاس User
در این بخش، کلاس User را ایجاد میکنیم که نهاد کاربر را در فرایند احراز هویت نمایندگی میکند. بدین منظور باید در ادامه فایل src/User/User.php را با محتوای زیر ایجاد کنیم:
نکته مهم این است که کلاس User باید به پیادهسازی اینترفیس UserInterface در کامپوننت امنیت سیمفونی بپردازد. به جز آن هیچ چیز نامعمولی در این بخش وجود ندارد.
کلاس ارائهدهنده پایگاه داده
بارگذاری کاربران از بکاند در حیطه وظایف ارائهدهنده کاربر است. در این بخش یک پایگاه داده ارائهدهنده کاربر میسازیم که کاربر را از پایگاه داده MySQL بارگذاری میکند:
ارائهدهنده کاربر باید اینترفیس UserProviderInterface را پیادهسازی کند. ما از دکترین DBAL برای اجرای عملیات مرتبط با پایگاه داده استفاده میکنیم. از آنجا که ما اینترفیس UserProviderInterface را پیادهسازی کردهایم، باید متدهای loadUserByUsername، refreshUser و supportsClass را نیز پیادهسازی کنیم.
متد loadUserByUsername باید کاربر را بر اساس «نام کاربری» (username) وی بارگذاری کند و این کار در متد getUser صورت میگیرد. اگر کاربر پیدا شود، شیء Sfauth\User\User متناظر را بازگشت میدهیم که اینترفیس UserInterface را پیادهسازی میکند. از سوی دیگر، متد refreshUser اقدام به تازهسازی شیء User ارائه شده از طریق واکشی جدیدترین اطلاعات از پایگاه داده میکند.
در نهایت متد supportsClass بررسی میکند که آیا ارائهدهنده DatabaseUserProvider از کلاس کاربر ارائه شده پشتیبانی میکند یا نه.
کلاس پایگاه داده ارائهدهنده احراز هویت
در نهایت ما باید ارائهدهنده احراز هویت کاربر را که به تعریف منطق احراز هویت، یعنی چگونگی احراز شدن هویت کاربر میپردازد، پیادهسازی کنیم. در مورد مثال خودمان، باید اطلاعات کاربر را با پایگاه داده MySQL مطابقت دهیم و از این رو باید منطق احراز هویت را نیز بر همین مبنا تعریف کنیم.
بدین ترتیب در ادامه فایل src/User/DatabaseAuthenticationProvider.php را با محتوای زیر ایجاد میکنیم:
ارائهدهنده احراز هویت با نام DatabaseAuthenticationProvider به بسط کلاس مجرد UserAuthenticationProvider میپردازد. از این رو باید متدهای مجرد retrieveUser و checkAuthentication را نیز پیادهسازی کنیم.
وظیفه متد retrieveUser بارگذاری کاربر از ارائهدهنده کاربر متناظر است. در مورد مثال ما، این متد از ارائهدهنده کاربر DatabaseUserProvider برای بارگذاری کاربر از پایگاه داده MySQL استفاده خواهد کرد.
از سوی دیگر، متد checkAuthentication بررسیهای مورد نیاز را برای احراز هویت کاربر جاری اجرا میکند. دقت کنید که ما از متد MD5 برای رمزنگاری رمزعبور استفاده کردهایم. البته شما باید از متدهای رمزنگاری امنتر برای ذخیرهسازی رمزهای عبور کاربر استفاده کنید.
جمعبندی طرز کار کد
تا به اینجا ما همه عناصر مورد نیاز برای احراز هویت را ایجاد کردهایم. در این بخش خواهیم دید که چگونه همه این عناصر در کنار هم قرار میگیرند تا کارکرد احراز هویت کاربر راهاندازی شود. در ادامه فایل db_auth.php را ایجاد کرده و آن را با محتوای زیر بهروزرسانی کنید:
به خاطر داشته باشید که در گردش کار احراز هویت که در ابتدای این مقاله مورد بررسی قرار دادیم، به همین توالی کارهایی که در کد فوق میبینید، اشاره کرده بودیم. نخستین چیزی که باید بازیابی شود اطلاعات کاربر است و به وسیله آن یک توکن احراز نشده میسازیم.
سپس توکن را به بخش مدیریت احراز هویت ارسال میکنیم تا مورد اعتبار سنجی قرار گیرد.
زمانی که متد احراز هویت فراخوانی میشود، چیزهای زیادی در پسزمینه اجرا میشوند. در ابتدا بخش مدیریت احراز هویت اقدام به گزینش ارائهدهنده مناسب احراز هویت میکند. در مورد مثال ما، این همان ارائهدهنده احراز هویت با نام DatabaseAuthenticationProvider است که برای احراز هویت گزینش خواهد شد.
سپس اقدام به بازیابی کاربر به وسیله نام کاربری از ارائهدهنده کاربر به نام DatabaseUserProvider میکنیم. در نهایت متد checkAuthentication بررسیهای لازم برای احراز هویت درخواست کاربر جاری را انجام میدهد.
اگر میخواهید اسکریپت db_auth.php را تست کنید، باید یک جدول sf_users در پایگاه داده MySQL بسازید.
در ادامه اسکریپت db_auth.php را اجرا کنید تا طرز کار آن را ببینید. با تکمیل موفقیتآمیز آن شما میتوانید یک توکن احراز هویت را چنان که در قطعه کد زیر میبینید دریافت کنید.
زمانی که کاربر احراز هویت شد، میتوانید توکن احراز هویت را در یک «سِشِن» (Session) ذخیره کنید تا برای درخواستهای بعدی استفاده شود. به این ترتیب دموی احراز هویت ساده ما تکمیل میشود.
سخن پایانی
در این مقاله به بررسی کامپوننت امنیت سیمفونی پرداختیم که به ما امکان میدهد تا امکانات امنیتی را در اپلیکیشنهای PHP خود داشته باشیم. به طور خاص ما به بررسی امکان احراز هویت پرداختیم که در کامپوننت فرعی symfony/security-core ارائه شده است و با ارائه نمونهای از پیادهسازی آن در یک اپلیکیشن PHP مثالی از طرز کار آن ارائه کردیم.
اگر این نوشته برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی PHP
- مجموعه آموزش های برنامه نویسی
- آموزش پروژه محور PHP — مجموعه مقالات جامع وبلاگ فرادرس
- نوشتن و خواندن فایل ها با PHP — به زبان ساده
- شیوه استفاده از نشست ها (Session) در PHP — به زبان ساده
==