اكتشف إطار PHP Laravel


الدرس: المصادقة authentification


الصفحة السابقة
المصادقة مهمة متكررة. في الواقع ، غالبًا ما تكون هناك أجزاء من الموقع يجب أن تكون متاحة فقط لبعض المستخدمين ، إذا كانت الإدارة فقط. الحل المقترح من قبل Laravel بسيط للغاية لأن كل شيء جاهز بالفعل كما سنرى في هذا الفصل.

Artisan


تم تجهيز Laravel الإصدار 5.0 مع طرق(Routes) العرض(Views) والأصول(assets) وطرق المصادقة ( authentification ) .شهد وصول الإصدار 5.1 اختفاء هذه العناصر بعد مناقشات عديدة وحيوية. أخيرًا ، مع الإصدار 5.2 ، ما زلنا لا نملك كل هذا الأساسي ولكن هناك أمر Artisan لإنشاءه. لذلك سوف نستخدم هذا الأمر:

php artisan make:auth
إذا سارت الأمور على ما يرام ، يجب أن يكون لديك هذه الآراء:
framework Laravel MVC
عرض المصادقة
يجب أن تجد أيضًا وحدة تحكم جديدة:
framework Laravel MVC
وحدة تحكم جديدة
وفي المسارات ملف هذا الكود الجديد:

<?php
Route::auth();
Route::get('/home', 'HomeController@index');
أنت الآن جاهز لهذا الفصل!
Route::auth()  يولد تلقائيا جميع طرق المصادقة

الجداول


جدول المستخدمين
سوف نستخدم الجدول users  الذي أنشأناه في الفصل السابق. تلقائيا ، يعتبر Laravel أن هذا الجدول موجود ويستخدمه كمرجع للمصادقة.
تلقائيا أيضا Eloquent هو الذي يستخدم كبرنامج تشغيل (driver) ، ومن الممكن أيضا تغيير هذه العملية.
جدول password_reset
أثناء التثبيت ، يوجد ترحيلان موجودان:
framework Laravel MVC
الترحيلات 2 موجودة في التثبيت
في الفصول السابقة ، قمت بحذف الفصل الثاني لأننا نحتاج فقط إلى جدول المستخدم. في هذا الفصل ، سنحتاج إلى الجدول الثاني الذي سيتم استخدامه لإعادة تعيين كلمات المرور.
سنقوم بالقليل من التنظيف من خلال إطلاق أمر Artisan لحذف جميع الجداول التي قمت بإنشائها:

php artisan migrate:reset
يجب أن يكون لديك فقط الجدول migrations  فارغا  . إذا لم يكن كذلك ، قم بما يلزم في قاعدتك.
مع وجود الترحيلين ، قم بتشغيل الأمر الArtisan لإنشاء الجداول:

php artisan migrate
يجب عليك عادة الحصول على هذا:
framework Laravel MVC
الجداول 3
الآن بعد أن أصبحت الجداول جاهزة ، دعنا ننتقل.
حافظ على الترحيل الذي قمنا به في الفصول السابقة للمستخدمين الذين لديهم العمود   admin . لا تستخدم هذا المرفق مع Laravel والذي لا يتضمن هذا العمود.

الوسيطة middlewares


ما هي الوسيطة؟
فيما يلي رسم تخطيطي صغير لتوضيح هذا:
framework Laravel MVC
المواقع الوظيفية للوسيطة
الوسيطة تنفذ المعالجة عند وصول الطلب أو عند مغادرته. على سبيل المثال ، تتم إدارة الجلسات أو ملفات تعريف الارتباط في Laravel في البرامج الوسيطة ، وكذلك المصادقة. لدينا بالفعل العديد من البرامج الوسيطة ، يقوم كل منها بمعالجته وينقل الطلب أو الاستجابة إلى التالي.
يقوم Laravel بتثبيت ملفين للوسيطة يتعلقان بالمصادقة:
framework Laravel MVC
الوسيطة للمصادقة
مصادقة Authenticate
تسمح هذه الوسيطة بمعرفة ما إذا كان المستخدم غير مصادق. هنا هو كوده.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class Authenticate
{
    /**
     * Handle an incoming request.
     *
     * @param    \Illuminate\Http\Request  $request
     * @param    \Closure  $next
     * @param    string|null  $guard
     * @return  mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->guest()) {
            if ($request->ajax() || $request->wantsJson()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->guest('login');
            }
        }

        return $next($request);
    }
}
نتحقق مما إذا كان المستخدم مجرد ضيف ( guest) . إذا كانت هذه هي الحالة ، فنحن نختبر ما إذا كان الطلب في Ajax ، وفي هذه الحالة نعود   Unauthorized . إذا لم يكن في Ajax ، فنحن نعيد التوجيه إلى الطريق   login حتى يتسنى للضيف المصادقة. إذا لم يكن ضيفًا ، فيُسمح للطلب بمتابعة مساره بشكل طبيعي. من الواضح أن كل هذا لم يتم وضعه بصفة دائمة ويمكننا تغيير أي شيء نريده. في هذه الدورة التدريبية ، سأتناول الكود التلقائي فقط.
هذه الطريقة   redirect()->guest  تعادل الطريقة   redirect() مع اختلاف حفظ عنوان URL في الجلسة لتتمكن من إعادة توجيه المستخدم في نهاية مصادقته إلى عنوان URL الذي أراد الوصول إليه في البداية.
RedirectIfAuthenticated
تسمح هذه الوسيطة بمعرفة ما إذا كان المستخدم مصادقًا أم لا. لذلك هو عكس ما سبق. هنا هو كوده:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param    \Illuminate\Http\Request  $request
     * @param    \Closure  $next
     * @param    string|null  $guard
     * @return  mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/');
        }

        return $next($request);
    }
}
إذا تمت المصادقة على المستخدم ، والذي تمت الإشارة إليه بواسطة الطريقة    check، فسنعود إلى الصفحة الأساسية للموقع ( /) . خلاف ذلك تركنا الطلب يعمل بشكل طبيعي.

الطرق والتحكم


الطرق
رأينا أننا أنشأنا طرقًا مع الArtisan :

<?php
Route::auth();
Route::get('/home', 'HomeController@index');
نظرًا لأنه ليس واضحًا للغاية ، دعنا نرى القليل من الطرق التي تم إنشاؤها بهذه الطريقة:
framework Laravel MVC framework Laravel MVC
الطرق التي تم إنشاؤها
سنقوم بتحليل كل هذا في هذا الفصل.
وحدات التحكم
يشار إلى اثنين من وحدات التحكم وجدت هنا:
framework Laravel MVC
وحدات تحكم المصادقة اثنين
AuthController
تهدف وحدة التحكم هذه إلى إدارة:
  1. تسجيل المستخدم
  2. الاتصال
  3. الانفصال
إذا نظرنا إلى كوده:

<?php

namespace App\Http\Controllers\Auth;

use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;

class AuthController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Registration & Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users, as well as the
    | authentication of existing users. By default, this controller uses
    | a simple trait to add these behaviors. Why don't you explore it?
    |
    */

    use AuthenticatesAndRegistersUsers, ThrottlesLogins;

    /**
     * Where to redirect users after login / registration.
     *
     * @var  string
     */
    protected $redirectTo = '/';

    /**
     * Create a new authentication controller instance.
     *
     * @return  void
     */
    public function __construct()
    {
        $this->middleware($this->guestMiddleware(), ['except' => 'logout']);
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param    array  $data
     * @return  \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|min:6|confirmed',
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param    array  $data
     * @return  User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }
}
لم يتم العثور على أي من الطرق المشار إليها في الطرق. يمكنك ملاحظة استخدام السطر   Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers . لذلك كل الأساليب موجودة في الإطار نفسه. إذا كنا بحاجة إلى تخصيصها ، فإن الحل الوحيد هو زيادة التحميل عليها.
يهدف الخط  ThrottlesLogins  إلى توفير الحماية ضد هجمات "القوة الغاشمة".
PasswordController
وحدة التحكم فقط هي المُخولة للسماح بإعادة تعيين كلمة المرور في حالة نسيانها من قبل المستخدم. إذا نظرنا أيضًا إلى الكود:

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;

class PasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset requests
    | and uses a simple trait to include this behavior. You're free to
    | explore this trait and override any methods you wish to tweak.
    |
    */

    use ResetsPasswords;

    /**
     * Create a new password controller instance.
     *
     * @return  void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }
}
نحن ندرك أنه أيضًا يستخدم خطًا ( Illuminate\Foundation\Auth\ResetsPasswords) .

العرض


سوف تجد العرض هنا:
framework Laravel MVC
عرض المصادقة
من الواضح أنك لست ملزمًا باستخدام طرق العرض هذه إذا كنت ترغب في دمجها بصريًا في أحد المواقع (هذا ما سيتم القيام به خلال نشاط هذا الفصل) ولكننا سنستخدمها في هذا الفصل. مباشرة. كلها مصممة بنفس الطريقة. فيما يلي على سبيل المثال طريقة عرض الاتصال ( resources/views/auth/login.blade.php) :

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Login</div>
                <div class="panel-body">
                    <form class="form-horizontal" role="form" method="POST" action="{ { url('/login') }}">
                        {!! csrf_field() !!}

                        <div class="form-group{ { $errors->has('email') ? ' has-error' : '' }}">
                            <label class="col-md-4 control-label">E-Mail Address</label>

                            <div class="col-md-6">
                                <input type="email" class="form-control" name="email" value="{ { old('email') }}">

                                @if ($errors->has('email'))
                                    <span class="help-block">
                                        <strong>{ { $errors->first('email') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group{ { $errors->has('password') ? ' has-error' : '' }}">
                            <label class="col-md-4 control-label">Password</label>

                            <div class="col-md-6">
                                <input type="password" class="form-control" name="password">

                                @if ($errors->has('password'))
                                    <span class="help-block">
                                        <strong>{ { $errors->first('password') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <div class="checkbox">
                                    <label>
                                        <input type="checkbox" name="remember"> Remember Me
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    <i class="fa fa-btn fa-sign-in"></i>Login
                                </button>

                                <a class="btn btn-link" href="{ { url('/password/reset') }}">Forgot Your Password?</a>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
من الواضح أن كل شيء باللغة الإنجليزية! من ناحية أخرى ، نرى أننا نستخدم قالبًا ( app) .

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


التحقق من صحة
في وحدة التحكم  AuthController تجد هذا الكود:

<?php
protected function validator(array $data)
{
    return Validator::make($data, [
        'name' => 'required|max:255',
        'email' => 'required|email|max:255|unique:users',
        'password' => 'required|min:6|confirmed',
    ]);
}
لقد رأينا حتى الآن التحقق من الصحة من طلب نموذج وهناك يتم بشكل مختلف. ربما لأنه كان من الصعب على الإطار إدارة مساحات الأسماء بشكل صحيح في هذه الحالة. نجد أيضًا في هذه الفئة طريقة لإنشاء المستخدم:

<?php
protected function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => bcrypt($data['password']),
    ]);
}
نظرًا لأننا أضفنا عمودًا ، admin يتعين علينا تعديل الكود قليلاً لحفظها أيضًا:

<?php
public function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => bcrypt($data['password']),
        'admin' => isset($data['admin'])    
    ]);
}
انتبه ، في الفصل السابق أنشأنا في نموذج المستخدم mutator لتشفير كلمة المرور تلقائيًا ، إذا قمت بتشفيرها مرتين فستواجه مشاكل! لذلك عليك أن تختار الطريقة التي تريد استخدامها.
وحدة التحكم
قبل التفكير في المصادقة ، يجب أن يكون الزائر قادرًا على التسجيل.
إذا نظرنا إلى محتوى السطر ،  AuthenticatesAndRegistersUsers فإننا ندرك أنه يستخدم سطرين آخرين:

<?php

namespace Illuminate\Foundation\Auth;

trait AuthenticatesAndRegistersUsers
{
    use AuthenticatesUsers, RegistersUsers {
        AuthenticatesUsers::redirectPath insteadof RegistersUsers;
        AuthenticatesUsers::getGuard insteadof RegistersUsers;
    }
}
هناك طريقتان في السطر RegistersUsers لتسجيل المستخدم:

<?php

namespace Illuminate\Foundation\Auth;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

trait RegistersUsers
{
    use RedirectsUsers;

    /**
     * Show the application registration form.
     *
     * @return  \Illuminate\Http\Response
     */
    public function getRegister()
    {
        return $this->showRegistrationForm();
    }

    /**
     * Show the application registration form.
     *
     * @return  \Illuminate\Http\Response
     */
    public function showRegistrationForm()
    {
        if (property_exists($this, 'registerView')) {
            return view($this->registerView);
        }

        return view('auth.register');
    }

    /**
     * Handle a registration request for the application.
     *
     * @param    \Illuminate\Http\Request  $request
     * @return  \Illuminate\Http\Response
     */
    public function postRegister(Request $request)
    {
        return $this->register($request);
    }

    /**
     * Handle a registration request for the application.
     *
     * @param    \Illuminate\Http\Request  $request
     * @return  \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $validator = $this->validator($request->all());

        if ($validator->fails()) {
            $this->throwValidationException(
                $request, $validator
            );
        }

        Auth::guard($this->getGuard())->login($this->create($request->all()));

        return redirect($this->redirectPath());
    }

    /**
     * Get the guard to be used during registration.
     *
     * @return  string|null
     */
    protected function getGuard()
    {
        return property_exists($this, 'guard') ? $this->guard : null;
    }
}
دعنا نلقي نظرة فاحصة على هاتين الطريقتين:
  • getRegister  : نرجع هنا طريقة العرض   auth.register التي يجب أن تحتوي على نموذج للتسجيل (لاحظ أنه تم اختباره لوجود خاصية ممكن   registerView والذي يسمح بتغيير الموقع واسم العرض بسهولة عن طريق إنشاء هذه الخاصية.
  • postRegister  : هنا نقوم بمعالجة تقديم النموذج ، يتم ضمان التحقق من الصحة بالطريقة  validator التي رأيناها أعلاه ، وإذا كانت عملية التحقق صحيحة فنحن ننشئها في قاعدة البيانات هذا المستخدم مع الطريقة    create، نحن نربط المستخدم الجديد مع الطريقة    login، أخيرًا نشير إلى عنوان url المحدد في الطريقة   redirectPath .
نظرًا لأن كل هذا الكود موجود في الإطار ، فلا ينبغي لنا تعديله مباشرةً. ومع ذلك يمكنك تعديل رابط إعادة التوجيه. انظر إلى الطريقة redirectPath الموضوعة في السطر RedirectUsers :

<?php
public function redirectPath()
{
    if (property_exists($this, 'redirectPath'))
    {
        return $this->redirectPath;
    }

    return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
نحن نلاحظ وجود خاصية redirectPath . إذا كانت موجودة ، فإننا نستخدمها لإعادة التوجيه. نحن أيضًا نختبر وجود خاصية   redirectTo، وإلا فإننا نعيد التوجيه إلى   home . لذلك إذا كنت ترغب في إعادة توجيه محددة فقط إنشاء خاصية  redirectPath أو  redirectTo في وحدة تحكم. لأي تعديل آخر ، يجب أن تكون الأساليب محمّلة.
عنوان url هو    .../register .
العرض auth.register
نحن بحاجة إلى عرض للتسجيل ، ورأينا أن Laravel يقدم لنا واحدة. هنا هو الجانب الذي يتم الحصول عليه عادة:
framework Laravel MVC
نموذج التسجيل
عندما يتم إنشاء المستخدم وتسجيل الدخول ، يتم إعادته إلى المسار المحدد بواسطة الوظيفة   redirectPath التي رأيناها أعلاه. كما يتم توفير الطرق ، وحدة التحكم وطريقة العرض ، نحصل على:
framework Laravel MVC
المستخدم المسجل و متصل

الاتصال والانقطاع


الآن بعد أن أصبح بإمكان المستخدمين التسجيل ، دعنا نذهب إلى الاتصال. بشكل تلقائي ، تخطط Laravel للقيام بذلك من عنوان البريد الإلكتروني. سوف نحافظ على هذا السلوك.
الاتصال
هناك طريقتان مشتركتان في السمة  AuthenticatesUsers  :

<?php

namespace Illuminate\Foundation\Auth;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Lang;

trait AuthenticatesUsers
{
    use RedirectsUsers;

    /**
     * Show the application login form.
     *
     * @return  \Illuminate\Http\Response
     */
    public function getLogin()
    {
        return $this->showLoginForm();
    }

    /**
     * Show the application login form.
     *
     * @return  \Illuminate\Http\Response
     */
    public function showLoginForm()
    {
        $view = property_exists($this, 'loginView')
                    ? $this->loginView : 'auth.authenticate';

        if (view()->exists($view)) {
            return view($view);
        }

        return view('auth.login');
    }

    /**
     * Handle a login request to the application.
     *
     * @param    \Illuminate\Http\Request  $request
     * @return  \Illuminate\Http\Response
     */
    public function postLogin(Request $request)
    {
        return $this->login($request);
    }

    /**
     * Handle a login request to the application.
     *
     * @param    \Illuminate\Http\Request  $request
     * @return  \Illuminate\Http\Response
     */
    public function login(Request $request)
    {
        $this->validateLogin($request);

        // If the class is using the ThrottlesLogins trait, we can automatically throttle
        // the login attempts for this application. We'll key this by the username and
        // the IP address of the client making these requests into this application.
        $throttles = $this->isUsingThrottlesLoginsTrait();

        if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        $credentials = $this->getCredentials($request);

        if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
            return $this->handleUserWasAuthenticated($request, $throttles);
        }

        // If the login attempt was unsuccessful we will increment the number of attempts
        // to login and redirect the user back to the login form. Of course, when this
        // user surpasses their maximum number of attempts they will get locked out.
        if ($throttles && ! $lockedOut) {
            $this->incrementLoginAttempts($request);
        }

        return $this->sendFailedLoginResponse($request);
    }

    /**
     * Validate the user login request.
     *
     * @param    \Illuminate\Http\Request  $request
     * @return  void
     */
    protected function validateLogin(Request $request)
    {
        $this->validate($request, [
            $this->loginUsername() => 'required', 'password' => 'required',
        ]);
    }

    /**
     * Send the response after the user was authenticated.
     *
     * @param    \Illuminate\Http\Request  $request
     * @param    bool  $throttles
     * @return  \Illuminate\Http\Response
     */
    protected function handleUserWasAuthenticated(Request $request, $throttles)
    {
        if ($throttles) {
            $this->clearLoginAttempts($request);
        }

        if (method_exists($this, 'authenticated')) {
            return $this->authenticated($request, Auth::guard($this->getGuard())->user());
        }

        return redirect()->intended($this->redirectPath());
    }

    /**
     * Get the failed login response instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return  \Illuminate\Http\Response
     */
    protected function sendFailedLoginResponse(Request $request)
    {
        return redirect()->back()
            ->withInput($request->only($this->loginUsername(), 'remember'))
            ->withErrors([
                $this->loginUsername() => $this->getFailedLoginMessage(),
            ]);
    }

    /**
     * Get the failed login message.
     *
     * @return  string
     */
    protected function getFailedLoginMessage()
    {
        return Lang::has('auth.failed')
                ? Lang::get('auth.failed')
                : 'These credentials do not match our records.';
    }

    /**
     * Get the needed authorization credentials from the request.
     *
     * @param    \Illuminate\Http\Request  $request
     * @return  array
     */
    protected function getCredentials(Request $request)
    {
        return $request->only($this->loginUsername(), 'password');
    }

    /**
     * Log the user out of the application.
     *
     * @return  \Illuminate\Http\Response
     */
    public function getLogout()
    {
        return $this->logout();
    }

    /**
     * Log the user out of the application.
     *
     * @return  \Illuminate\Http\Response
     */
    public function logout()
    {
        Auth::guard($this->getGuard())->logout();

        return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
    }

    /**
     * Get the guest middleware for the application.
     */
    public function guestMiddleware()
    {
        $guard = $this->getGuard();

        return $guard ? 'guest:'.$guard : 'guest';
    }

    /**
     * Get the login username to be used by the controller.
     *
     * @return  string
     */
    public function loginUsername()
    {
        return property_exists($this, 'username') ? $this->username : 'email';
    }

    /**
     * Determine if the class is using the ThrottlesLogins trait.
     *
     * @return  bool
     */
    protected function isUsingThrottlesLoginsTrait()
    {
        return in_array(
            ThrottlesLogins::class, class_uses_recursive(static::class)
        );
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return  string|null
     */
    protected function getGuard()
    {
        return property_exists($this, 'guard') ? $this->guard : null;
    }
}
دعنا نلقي نظرة فاحصة على هاتين الطريقتين:
  • getLogin  : نرجع هنا طريقة العرض    auth.login (ما لم تكن هناك طريقة عرض   auth.authenticate أو قد أنشأنا خاصية    loginView ) والتي يجب أن تحتوي على نموذج الاتصال.
  • postLogin  : هنا نتعامل مع تقديم النموذج ، يتم التحقق من الصحة مباشرة في الطريقة مع طريقة قوية  validate وهو بديل مثير للاهتمام لطلبات النموذج. إذا كان التحقق من الصحة صحيحًا ، فإننا نتحقق من عدم وجود هجوم (throttle) ثم يتم التحقق من البيانات في الجدول باستخدام الطريقة   attempt . إذا سارت الأمور على ما يرام ، فإننا نرجع كما حددتها الطريقة    handleUserWasAuthenticated، وإلا فإننا نعيد التوجيه إلى النموذج برسالة خطأ محددة بواسطة الوظيفة    getFailedLoginMesssage .
على مدار التغييرات ، تم تنفيذ العديد من الوظائف لتجنب التحميل الزائد لوحدة التحكم ، في كل حالة من الضروري النظر إلى الكود بعناية لتحديد أفضل إستراتيجية يتم تبنيها.
عنوان url هو    .../login .
عرض auth.login
ومن المقرر أيضا هذا العرض. إليك مظهر نموذج تسجيل الدخول:
framework Laravel MVC
نموذج تسجيل الدخول
إذا كان هناك بالفعل مستخدم قام بتسجيل الدخول ، فسيتم محاصرتك بواسطة الوسيطة للوصول إلى هذا النموذج. افصل المستخدم من القائمة أو احذف ملفات تعريف الارتباط المخزنة بواسطة المتصفح.
انفصال
في شريط القوائم ، يتم توفير تسجيل الخروج:
framework Laravel MVC
الأمر قطع الاتصال
هنا هي الطريقة المعنية في السطر   AuthenticatesUsers  :

<?php
/**
 * Log the user out of the application.
 *
 * @return  \Illuminate\Http\Response
 */
public function getLogout()
{
    return $this->logout();
}

/**
 * Log the user out of the application.
 *
 * @return  \Illuminate\Http\Response
 */
public function logout()
{
    Auth::guard($this->getGuard())->logout();

    return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
}
تم قطع اتصال المستخدم بالطريقة   logout ثم يتم إعادة توجيهه إلى جذر الموقع أو إلى المسار المحدد بواسطة الخاصية     redirectAfterLogout  إذا كانت موجودة ، وإلا إلى الجذر "/" .

نسيت كلمة المرور


هناك الجدول   password_resets في قاعدتنا:
framework Laravel MVC
جدول password_resets
نرى أننا سنحفظ هنا عنوان البريد الإلكتروني والرمز والطابع الزمني (تلقائيا ، الرموز صالحة لمدة ساعة واحدة).
لدينا أيضا وحدة تحكم:
framework Laravel MVC
تحكم PasswordController
سيكون لعناوين الموقع الشكل .../password/...
في نموذج الاتصال هناك رابط في حالة نسيان كلمة المرور: 
framework Laravel MVC
الرابط لنسيان كلمة المرور
عنوان URL المقابل هو  .../password/email
هنا هو مظهر النموذج:
framework Laravel MVC
نموذج نسيان كلمة المرور الخاصة بك
يطلب من المستخدم إدخال عنوان بريده الإلكتروني حتى يتمكن من العثور عليه في جدول المستخدمين.
هنا هو الكود في السطر   ResetsPasswords  :

<?php
/**
 * Display the form to request a password reset link.
 *
 * @return  \Illuminate\Http\Response
 */
public function getEmail()
{
    return $this->showLinkRequestForm();
}

/**
 * Display the form to request a password reset link.
 *
 * @return  \Illuminate\Http\Response
 */
public function showLinkRequestForm()
{
    if (view()->exists('auth.passwords.email')) {
        return view('auth.passwords.email');
    }

    return view('auth.password');
}

/**
 * Send a reset link to the given user.
 *
 * @param    \Illuminate\Http\Request  $request
 * @return  \Illuminate\Http\Response
 */
public function postEmail(Request $request)
{
    return $this->sendResetLinkEmail($request);
}

/**
 * Send a reset link to the given user.
 *
 * @param    \Illuminate\Http\Request  $request
 * @return  \Illuminate\Http\Response
 */
public function sendResetLinkEmail(Request $request)
{
    $this->validate($request, ['email' => 'required|email']);

    $broker = $this->getBroker();

    $response = Password::broker($broker)->sendResetLink($request->only('email'), function (Message $message) {
        $message->subject($this->getEmailSubject());
    });

    switch ($response) {
        case Password::RESET_LINK_SENT:
            return $this->getSendResetLinkEmailSuccessResponse($response);

        case Password::INVALID_USER:
        default:
            return $this->getSendResetLinkEmailFailureResponse($response);
    }
}
تم تقديم النموذج في الطريقة postEmail . 
لدينا حالتان:
  • المستخدم غير صالح (عنوان البريد الإلكتروني غير موجود): نحن نعيد التوجيه في النموذج مع رسالة الخطأ في المتغير error، مع هذا الجانب:
framework Laravel MVC
رسالة الخطأ لعنوان غير معروف
  • المستخدم صالح (أرسلنا إليه بريدًا إلكترونيًا): نقوم بإعادة التوجيه في النموذج مع رسالة في المتغير status .
framework Laravel MVC
تم إرسال البريد الإلكتروني.
ما هي الطريقة   trans ؟
إنه المساعد الذي يسمح لك بتكييف النص بناءً على قيمة المفتاح   locale في    config/app.php . سنرى هذا بالتفصيل في الفصل الخاص بالتوطين.
لكي يتم إرسال البريد الإلكتروني بشكل فعال ، يجب تكوين كل شيء بشكل صحيح في الملف   .env  :

MAIL_DRIVER=smtp
MAIL_HOST=smtp.free.fr
MAIL_PORT=25
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=""
وفي config/mail.php :

'from' => array('address' => 'moi@free.fr', 'name' => 'Administrateur'),
التكوين أعلاه يتوافق مع وضعي المحلي مع مزود الخدمة   free . بالنسبة لك يجب أن تكون مختلفة.
كيف تبدو رسالة البريد الإلكتروني المرسلة؟ يمكنك العثور على العرض المقابل هنا:
framework Laravel MVC
عرض للبريد الإلكتروني
مع هذا الكود:

Click here to reset your password: { { url('password/reset/'.$token) }}
انها واضحة وموجزة. دعونا نرى ما نحصل عليه في الاستقبال:

Click here to reset your password: { { url('password/reset/'.$token) }}
دعونا نرى ما حدث في جدول password_resets :
framework Laravel MVC
جدول password_reminders
لدينا تخزين عنوان البريد الإلكتروني ، الرمز المميز(token) ووقت الإنشاء.
 وإذا استخدمنا URL من البريد الإلكتروني فاننا نُوجه الى الطريق    password/reset ، وبالتالي فإن أسلوب    showResetForm  للخط    ResetsPasswords   :

<?php
/**
 * Display the password reset view for the given token.
 *
 * If no token is present, display the link request form.
 *
 * @param    \Illuminate\Http\Request  $request
 * @param    string|null  $token
 * @return  \Illuminate\Http\Response
 */
public function showResetForm(Request $request, $token = null)
{
    if (is_null($token)) {
        return $this->getEmail();
    }

    $email = $request->input('email');

    if (property_exists($this, 'resetView')) {
        return view($this->resetView)->with(compact('token', 'email'));
    }

    if (view()->exists('auth.passwords.reset')) {
        return view('auth.passwords.reset')->with(compact('token', 'email'));
    }

    return view('auth.reset')->with(compact('token', 'email'));
}
يتم تمرير الرمز المميز في متغير $token . نتحقق من وجودها وإلا فإننا نعيد النموذج. في حالة وجودها ، نرجع نموذج إدخال كلمة المرور الجديدة مع طريقة العرض reset في المجلد auth/passwords :
framework Laravel MVC
عرض إعادة التعيين
مع هذا الجانب:
framework Laravel MVC
نموذج كلمة المرور الجديدة
عند التقديم ، صادفنا طريقة الخط  postReset  :

<?php
/**
 * Reset the given user's password.
 *
 * @param    \Illuminate\Http\Request  $request
 * @return  \Illuminate\Http\Response
 */
public function postReset(Request $request)
{
    return $this->reset($request);
}

/**
 * Reset the given user's password.
 *
 * @param    \Illuminate\Http\Request  $request
 * @return  \Illuminate\Http\Response
 */
public function reset(Request $request)
{
    $this->validate(
        $request,
        $this->getResetValidationRules(),
        $this->getResetValidationMessages(),
        $this->getResetValidationCustomAttributes()
    );

    $credentials = $request->only(
        'email', 'password', 'password_confirmation', 'token'
    );

    $broker = $this->getBroker();

    $response = Password::broker($broker)->reset($credentials, function ($user, $password) {
        $this->resetPassword($user, $password);
    });

    switch ($response) {
        case Password::PASSWORD_RESET:
            return $this->getResetSuccessResponse($response);

        default:
            return $this->getResetFailureResponse($request, $response);
    }
}
هناك التحقق من صحة الإدخالات. إذا سارت الأمور على ما يرام ، يتم حفظ كلمة المرور الجديدة وتسجيل دخول المستخدم. لإعادة التوجيه سوف يعتمد بوضوح على النجاح أو الفشل.

في الخلاصة


  • يتم دعم المصادقة بالكامل وببساطة بواسطة Laravel .
  • الوسيطة تسمح بمعالجة عند وصول أو رحيل الطلب.
  • يمكن استخدام الوسيطة  Authenticate و   RedirectIfAuthenticated للسماح أو لرفض الوصول.
  • تم التخطيط لنظام تجديد كلمة المرور الكامل.