يأتي Laravel، وهذه إحدى ميزاته الكثيرة، مضمنّا بآليات استيثاق Authentication جاهزة للاستخدام. سنطبق في هذا الدرس آلية الاستيثاق على صفحة الدفع checkout
بحيث يُسمح بالدخول للمستخدمين المسجلين فقط.
هذا الدرس جزء من سلسلة تعلم Laravel والتي تنتهج مبدأ "أفضل وسيلة للتعلم هي الممارسة"، حيث ستكون ممارستنا عبارة عن إنشاء تطبيق ويب للتسوق مع ميزة سلة المشتريات. يتكون فهرس السلسلة من التالي:
- مدخل إلى Laravel 5.
- تثبيت Laravel وإعداده على كلّ من Windows وUbuntu.
- أساسيات بناء تطبيق باستخدام Laravel.
- إنشاء روابط محسنة لمحركات البحث (SEO) في إطار عمل Laravel.
- نظام Blade للقوالب.
- تهجير قواعد البيانات في Laravel.
- استخدام Eloquent ORM لإدخال البيانات في قاعدة البيانات، تحديثها أو حذفها.
- إنشاء سلة مشتريات في Laravel.
- الاستيثاق في Laravel. (هذا الدرس)
- إنشاء واجهة لبرمجة التطبيقات API في Laravel.
- إنشاء مدوّنة باستخدام Laravel.
- استخدام AngularJS واجهةً أمامية Front end لتطبيق Laravel.
- الدوّال المساعدة المخصّصة في Laravel.
- استخدام مكتبة Faker في تطبيق Laravel لتوليد بيانات وهمية قصدَ الاختبار.
يغطي الدرس المواضيع التالية:
- إعداد الاستيثاق في Laravel 5.
- أساسيات الاستيثاق في Laravel 5.
- تغيير رابط تسجيل الدخول المبدئي.
إعدادات الاستيثاق في Laravel 5
يوجد ملف إعداد الاستيثاق على المسار config/auth.php
. في ما يلي جزء من الملف:
'model' => App\User::class, 'table' => 'users', 'password' => [ 'email' => 'emails.password', 'table' => 'password_resets', 'expire' => 60, ],
يحدّد الملف:
- اسم نموذج الاستيثاق.
- اسم جدول المستخدمين.
- خيارات إعادة تعيين كلمة السر.
سنستخدم النموذج User
لاستيثاق المستخدمين. افتح الملف User.php
وعدّله على النحو التالي:
<?php namespace App; use Illuminate\Auth\Authenticatable; use Illuminate\Database\Eloquent\Model; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; class User extends Model implements AuthenticatableContract { use Authenticatable; /** * The database table used by the model. * * @var string */ protected $table = 'users'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['name', 'email', 'password']; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = ['password', 'remember_token']; }
فلنعرّج قليلا على الأصناف الجديدة علينا:
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
توجد في Laravel أصناف يطلق عليها اسم العقود Contracts. العقود هي مجموعة واجهات Interfaces تعرّف خدمات يوفّرها إطار العمل. تعرّف العقود دوال يحتاجها إطار العمل لتأدية الخدمة. يستورد السطر أعلاه العقد Authenticatable
وهي واجهة تعرّف الدوال الضرورية لاستيثاق المستخدمين. عند استيراد الواجهة أعطيناها الاسم AuthenticatableContract
حتى لا تختلط مع السمة Trait الذي يحمل نفس الاسم (نستعمله في نموذج المستخدم كما سنرى لاحقا).
يجب على الكائن الذي يستوثق من المستخدمين (نموذج المستخدم في حالتنا) أن ينجز Implement هذه الواجهة:
class User extends Model implements AuthenticatableContract
لإنجاز دوال الواجهة (تعرّف واجهة Authenticatable
الدوال دون أن تنجزها) نستخدم السمة Illuminate\Auth\Authenticatable
.
نستورده أولا:
use Illuminate\Auth\Authenticatable;
ثم نستخدمه:
use Authenticatable;
- يحدّد النموذج جدول البيانات المستخدم لتخزين بيانات المسجَّلين، ويفعّل الإسناد الشامل لبعض الحقول.
-
تعيّن مصفوفة
hidden$
بيانات المستخدم التي لا نودّ عرضها عند الإجابة على طلب عبر واجهة تطبيقات برمجية API (يجب إخفاء كلمة سر المستخدمpassword
ورمز الأمانremember_token
عن الخارج).
يأتي مع Laravel مبدئيا ملف تهجير لإنشاء جدول المستخدمين. افتح ملف التهجير 2014_10_12_000000_create_users_table.php
(قد يختلف الختم الزمني في اسم الملف حسب إصدار Laravel):
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password', 60); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('users'); } }
يعرّف ملف التهجير حقول جدول المستخدمين. تعيّن الدالة rememberToken
رمز حماية لتأمين المستخدمين ضدّ هجمات تزوير الطلب عبر الموقع CSRF.
استمارات التسجيل والولوج Login
يوجد في عرض الدخول login.blade.php
استمارتان، واحدة لتسجيل المستخدمين Registration والأخرى لدخولهم Login. افتح ملف العرض login
وحدّثه على النحو التالي:
@extends('layouts.layout') @section('content') <section id="form"><!--form--> <div class="container"> <div class="row"> <div class="col-sm-4 col-sm-offset-1"> <div class="login-form"><!--login form--> <h2>Login to your account</h2> <form method="POST" action="{{url('auth/login')}}"> {!! csrf_field() !!} <input type="email" name="email" id="email" placeholder="Email Address" /> <input type="password" name="password" id="password" placeholder="Password" /> <span> <input name="remember" id="remember" type="checkbox" class="checkbox"> Keep me signed in </span> <button type="submit" class="btn btn-default">Login</button> </form> </div><!--/login form--> </div> <div class="col-sm-1"> <h2 class="or">OR</h2> </div> <div class="col-sm-4"> <div class="signup-form"><!--sign up form--> <h2>New User Signup!</h2> <form method="POST" action="{{url('register')}}"> {!! csrf_field() !!} <input type="text" name="name" id="name" placeholder="Name"> <input type="email" name="email" placeholder="Email Address"/> <input type="password" name="password" placeholder="Password"> <button type="submit" class="btn btn-default">Signup</button> </form> </div><!--/sign up form--> </div> </div> </div> </section><!--/form--> @endsection
التغييرات الأساسية هنا هي:
-
تعريف رابط مناسب لاستمارتي التسجيل والدخول مع تحديد أن البيانات تُرسَل بإجراء
POST
:
// دخول المستخدمين <form method="POST" action="{{url('auth/login')}}"> // تسجيل المستخدمين <form method="POST" action="{{url('register')}}">
تُرسل بيانات الدخول إلى الرابط larashop.dev/auth/login
وبيانات التسجيل إلى الرابط larashop.dev/register
.
-
تضيف التعليمة
()csrf_field
حقلا أمنيا في الاستمارتين للحيلولة دون هجمات CSRF.
مسارات الدخول، الخروج والتسجيل
نضيف الآن المسارات الخاصة بالاستيثاق. افتح ملف المسارات routes.php
وأضف المسارات التالية:
// مسارات الدخول والخروج Route::get('auth/login', 'Front@login'); Route::post('auth/login', 'Front@authenticate'); Route::get('auth/logout', 'Front@logout'); // مسار التسجيل Route::post('/register', 'Front@register');
نعرّف المسار الذي يعرض استمارتي التسجيل والدخول:
Route::get('auth/login', 'Front@login');
نعرّف إجراء HTTP POST
الذي يوثّق المستخدمين:
Route::post('auth/login', 'Front@authenticate');
نعرّف مسار خروج المستخدم:
Route::get('auth/logout', 'Front@logout');
نعرف مسار تسجيل المستخدمين الجدد (إجراء HTTP POST
):
Route::post('/register', 'Front@register');
المسارات المَحمِيّة
مسار محمي هو مسار يطلُب من الزائر الدخول قبل الوصول إليه. سنحمي في هذه الفقرة الرابط http://larashop.dev/checkout
. يعني هذا أن المستخدمين المسجّلين فقط يمكنهم رؤية صفحة الدفع.
عدّل مسار checkout/
في ملف المسارات ليصبح على النحو التالي:
Route::get('/checkout', [ 'middleware' => 'auth', 'uses' => 'Front@checkout' ]);
تُنفّذ التعليمة
'middleware' => 'auth',
قبل دالة Front@checkout
؛ وتتحقق من دخول الزائر. فإن لم يكن سجّل دخوله توجّهه إلى الرابط auth/login/
، وتعرض له صفحة الدفع بعد الدخول.
دوال التسجيل والاستيثاق
نعدّل ملف المتحكّم لإضافة دوال تجيب على الطلبات القادمة من المسارات السابقة. افتح ملف المتحكم Front.php
لتعديله.
نبدأ باستيراد فضاءات الأسماء التي نحتاجها:
use App\User; use Illuminate\Support\Facades\Auth;
استوردنا نموذج المستخدم User
وفضاء الأسماء الخاص بالاستيثاق Auth
. توجد في فضاء الأسماء Auth
الدوال والكائنات التي نحتاجها للاستيثاق من المستخدمين.
تسجيل مستخدم جديد
public function register() { if (Request::isMethod('post')) { User::create([ 'name' => Request::get('name'), 'email' => Request::get('email'), 'password' => bcrypt(Request::get('password')), ]); } return Redirect::away('login'); }
تستخدم دالة التسجيل المعلومات المذكورة في استمارة التسجيل New User Signup!
لإنشاء مستخدم جديد عبر طلب الدالة User::create
(تعرّفنا على هذه الدالة خلال درس Eloquent ORM). ثم نوجّه الزائر بعد إلى صفحة الدخول. لاحظ استخدام الدالة bcrypt
أثناء تسجيل المستخدم. تعمّي هذه الدالة كلمة السر قبل تخزينها في جدول البيانات.
الاستيثاق من المستخدمين
تستوثق الدالة التالية من المستخدمين:
public function authenticate() { if (Auth::attempt(['email' => Request::get('email'), 'password' => Request::get('password')])) { return redirect()->intended('checkout'); } else { return view('login', array('title' => 'Welcome', 'description' => '', 'page' => 'home')); } }
ستوثق الدالة Auth::attempt
من المستخدم بناء على عنوان البريد email
وكلمة السر password
الذين أرسلتهما استمارة الدخول. في حال نجاح دخول المستخدم يُعاد توجيهه إلى صفحة الدفع checkout
عبر الدالة ()redirect
.
تسجيل خروج المستخدمين
يؤدي طلب الدالة Auth::logout
إلى تسجيل خروج المستخدمين بعد دخولهم عبر الدالة السابقة. عدّل دالة logout
الموجودة في ملف المتحكم لتصبح كالتالي:
public function logout() { Auth::logout(); return Redirect::away('auth/login'); }
تخرج الدالة المستخدم وتوجهه إلى صفحة الدخول.
إظهار بيانات الدخول في العرض
نحتاج، قبل اختبار التسجيل والدخول، إجراء تغيير أخير. تُظهر الصورة التالية الشريط العلوي الأيمن من الموقع:
نريد أن يظهر الشريط على النحو التالي بعد دخول المستخدم:
نريد أن يظهر اسم المستخدم بعد الدخول، وإبدال رابط Login
بـLogout
.
افتح ملف العرض layout.blade.php
للتعديل عليه. تذكر أن هذا هو العرض الرئيس الذي تمدّده بقية العروض. نغيّر جزئية الترويسة (header
) من ملف العرض لتصبح كالتالي:
<header id="header"><!--header--> <div class="header_top"><!--header_top--> <div class="container"> <div class="row"> <div class="col-sm-6"> <div class="contactinfo"> <ul class="nav nav-pills"> <li><a href="#"><i class="fa fa-phone"></i> +2 95 01 88 821</a></li> <li><a href="#"><i class="fa fa-envelope"></i> info@domain.com</a></li> </ul> </div> </div> <div class="col-sm-6"> <div class="social-icons pull-right"> <ul class="nav navbar-nav"> <li><a href="#"><i class="fa fa-facebook"></i></a></li> <li><a href="#"><i class="fa fa-twitter"></i></a></li> <li><a href="#"><i class="fa fa-linkedin"></i></a></li> <li><a href="#"><i class="fa fa-dribbble"></i></a></li> <li><a href="#"><i class="fa fa-google-plus"></i></a></li> </ul> </div> </div> </div> </div> </div><!--/header_top--> <div class="header-middle"><!--header-middle--> <div class="container"> <div class="row"> <div class="col-sm-4"> <div class="logo pull-left"> <a href="{{url('')}}"><img src="{{asset('images/home/logo.png')}}" alt="" /></a> </div> </div> <div class="col-sm-8"> <div class="shop-menu pull-right"> <ul class="nav navbar-nav"> <li><a href="#"><i class="fa fa-user"></i> {{Auth::check() ? Auth::user()->name : 'Account'}}</a></li> <li><a href="{{url('checkout')}}"><i class="fa fa-crosshairs"></i> Checkout</a></li> <li><a href="{{url('cart')}}"><i class="fa fa-shopping-cart"></i> Cart</a></li> <li><a href="{{Auth::check() ? url('auth/logout') : url('auth/login')}}"><i class="fa fa-lock"></i> {{Auth::check() ? 'Logout' : 'Login'}}</a></li> </ul> </div> </div> </div> </div> </div><!--/header-middle--> <div class="header-bottom"><!--header-bottom--> <div class="container"> <div class="row"> <div class="col-sm-9"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="mainmenu pull-left"> <ul class="nav navbar-nav collapse navbar-collapse"> <li><a href="{{url('')}}" {{$page == 'home' ? 'class=active' : ''}}>Home</a></li> <li><a href="{{url('products')}}" {{$page == 'products' ? 'class=active' : ''}}>Products</a></li> <li><a href="{{url('blog')}}" {{$page == 'blog' ? 'class=active' : ''}}>Blog</a></li> <li><a href="{{url('contact-us')}}" {{$page == 'contact_us' ? 'class=active' : ''}}>Contact Us</a></li> </ul> </div> </div> <div class="col-sm-3"> <div class="search_box pull-right"> <input type="text" placeholder="Search"/> </div> </div> </div> </div> </div><!--/header-bottom--> </header><!--/header-->
أضفنا التغييرين التاليين على ترويسة العرض:
-
إبدال
Account
بالتعليمة:{{Auth::check() ? Auth::user()->name : ‘Account’}}
نستعمل الدالة
Auth::check
للتحقق من دخول المستخدم؛ في حال الإيجاب نظهر اسمه بالدالةAuth::user
وإلا نبقي على عبارةAccount
. -
نفس المبدأ مع عبارة
Login
التي تصبح بعد الدخولLogout
، وتغيير الرابط بما يُناسب (larashop.dev/auth/login
للدخول وlarashop.dev/logout
للخروج).
افتح الرابط http://larashop.dev/auth/login
وسجل مستخدما جديد عبر الاستمارة New User Signup
.
بالضغط على زر Signup
تستدعي المسار http://laravel.dev/register
مع الإجراء POST
. تتولى دالة register
في المتحكم تلقي الطلب واستدعاء النموذج الذي ينشئ تسجيلة جديدة في جدول البيانات ثم تعيد الدالة توجيه المستخدم إلى صفحة الدخول. يمكنك التأكد من إنشاء المستخدم في الجدول users
ضمن قاعدة البيانات.
نجرّب الدخول بالمستخدم الجديد بإدخال عنوانه البريدي وكلمة السر في استمارة التسجيل.
إن أدخل بيانات مستخدم صالحة فستُنقل إلى صفحة الدفع. لاحظ أن اسم المستخدم وعبارة Logout
يظهران في الشريط العلوي.
ترجمة -وبتصرّف- للمقال Laravel 5 Authentication لصاحبه Rodrick Kazembe.
تم التعديل في بواسطة محمد أحمد العيل
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.