• 0

تسجيل الدخول عن طريق إسم المُستخدم او البريد الإلكتروني في Laravel

كيف يُمكن إتاحة تسجيل الدخول عن طريق إما البريد الإلكتروني او إسم المُستخدم في نفس الحقل.

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
  • 0

مرحباً،

يمكنك تسجيل الدخول عن طريق أحد الحلقين المذكورين ( البريد الالكتروني او اسم المستخدم) من خلال تنفيذ الخطوات التالية:

  • بالبداية بكل تأكيد يجب أن تكون قد أنشأت ملفات المصادقة auth scaffolding ، من خلال عدة خيارات متاحة أثناء بناء تطبيقك، مثلاً:
php artisan ui bootstrap --auth
  • بعدها تأكد من اضافة حقل username في جدول المستخدمين الخاص بك لتكون كالتالي:
    <?php
      
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
      
    class CreateUsersTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('users', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name');
                $table->string('email');
                $table->string('username')->nullable();
                $table->timestamp('email_verified_at')->nullable();
                $table->boolean('is_admin')->nullable();
                $table->string('password');
                $table->rememberToken();
                $table->timestamps();
            });
        }
      
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('users');
        }
    }

    ولا تنسى القيام بـ migrate في حال قمت بالتعديل على الملف السابق ليتم بناء قاعدة البيانات من جديد

  • في ملف واجهة تسجيل الدخول login blade قم بحذف حقل البريد الالكتروني email و إضافة حقل اسم المستخدم username كي يكون بديلا عنه (سنقوم بجعله يقبل الاثنين في الخطوة القادمة) عبر الكود التالي:
    <div class="form-group row">
        <label for="username" class="col-md-4 col-form-label text-md-right">Username Or Email</label>
       
        <div class="col-md-6">
            <input id="username" type="username" class="form-control @error('username') is-invalid @enderror" name="username" value="{{ old('username') }}" required  autofocus>
       
            @error('username')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </div>

     

  • الان سنقوم بتعديل تابع تسجيل الدخول login في ملف LoginController كي يحقق الوظيفة المطلوبة كالتالي:
    <?php
      
    namespace App\Http\Controllers\Auth;
      
    use App\Http\Controllers\Controller;
    use Illuminate\Foundation\Auth\AuthenticatesUsers;
    use Illuminate\Http\Request;
      
    class LoginController extends Controller
    {
      
        use AuthenticatesUsers;
        
        protected $redirectTo = '/home';
        /**
         * Create a new controller instance.
         *
         * @return void
         */
        public function __construct()
        {
            $this->middleware('guest')->except('logout');
        }
      
        /**
         * Create a new controller instance.
         *
         * @return void
         */
        public function login(Request $request)
        {   
            $input = $request->all();
      
            $this->validate($request, [
                'username' => 'required',
                'password' => 'required',
            ]);
      
            $fieldType = filter_var($request->username, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
            if(auth()->attempt(array($fieldType => $input['username'], 'password' => $input['password'])))
            {
                return redirect()->route('home');
            }else{
                return redirect()->route('login')
                    ->with('error','Email-Address And Password Are Wrong.');
            }
              
        }
    }

    يقوم التعديل السابق بفحص البيانات المدخلة في حقل username فإذا كانت بصيغة email فإنه سيقوم بمقارنتها بعمود البريد الالكتروني في قاعدة البيانات و الا فإنها اسم مستخدم و سيقارنها بحقل username بقاعدة البيانات.

     

1 شخص أعجب بهذا

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
  • 0

لنفترض أنه لديك حقل username في جدول المُستخدمين بهذا الشكل:

$table->string('username')->unique();

الآن يجب أن تُعدل على نموذج تسجيل الدخول و بالضبط في حقل البريد ليُصبح بهذا الشكل:

<div class="form-group row">
  <label for="login" class="col-md-4 col-form-label text-md-right">{{ __('Username or Email') }}</label>

  <div class="col-md-6">
    <input id="login" type="text"
           class="form-control{{ $errors->has('username') || $errors->has('email') ? ' is-invalid' : '' }}"
           name="login" value="{{ old('username') ?: old('email') }}" required autofocus>

    @if ($errors->has('username') || $errors->has('email'))
    <span class="invalid-feedback">
      <strong>{{ $errors->first('username') ?: $errors->first('email') }}</strong>
    </span>
    @endif
  </div>
</div>

في ملف login.blade.php، و هذا حتى يقبل الحقل إدخال نص و عرض رسائل الخطأ.

الآن يجب التعديل على المُتحكم LoginController سنُجري عليه بعض التعديلات حتى يُلائم الوضعية: 

نضيف الخاصية التالية للمُتحكم:

protected $username;

ثم من خلال الباني نقوم بتهيئة هذه الخاصية:

public function __construct()
{
	$this->middleware('guest')->except('logout');
	$this->username = $this->findUsername();
}

لاحظ أنها تأخذ قيمتها من خلال ما يُرجعه التابع findUsername لذلك نقوم بإنشائه في المتحكم أيضاً:

<?php

public function findUsername()
{
	$login = request()->input('login'); // جلب قيمة النص الذي أدخله المُستخدم في الحقل

	$fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; // بإستخدام القيمة يُمكننا معرفة إن كان المُدخل بريد او نص و على اساسها نضع نوع الحقل

	request()->merge([$fieldType => $login]); // وضع حقل جديد في الطلب

	return $fieldType; // email or username
}

كل ما يفعله التابع أنه يجلب لنا email او username على حسب القيمة المُدخلة و يضيف ذلك لمصفوفة الطلب:

إذا كان المُدخل بريداً:

'email' => 'قيمة الحقل'

إذا لم يكن بريد إلكتروني:

'username' => 'قيمة الحقل'

الآن نقوم بإعادة تعريف كل من التابع username و التابع login اللذان يستخدمها المُتحكم LoginController إعتمادًا على الTrait AuthenticatesUsers لن نُغير على التابع login كثيراً سنأخذه كما هو و نضيف بعض الأشياء فقط:

التابع username:

<?php

public function username()
{
  return $this->username;
}

التابع login:

<?php

public function login(Request $request)
{
  //نُغير التحقق
  $this->validate($request, [
    'login'    => 'required|string',
    'password' => 'required|string',
  ]);
	
  // نجلب نوع التسجيل
  $login_type = filter_var($request->input('login'), FILTER_VALIDATE_EMAIL)
    ? 'email'
    : 'username';

  // نضيفه لمصفوفة الطلب
  $request->merge([
    $login_type => $request->input('login')
  ]);

  // بقية الأشياء موجودة من الإطار نفسه و لن نغير فيها
  // 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.
  if (method_exists($this, 'hasTooManyLoginAttempts') &&
      $this->hasTooManyLoginAttempts($request)) {
    $this->fireLockoutEvent($request);

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

  if ($this->attemptLogin($request)) {
    return $this->sendLoginResponse($request);
  }

  // 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.
  $this->incrementLoginAttempts($request);

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

لا تنسى إستدعاء الكلاسات المُستخدم في المُتحكم.

هذا مُحتوى المُتحكم LoginController بعد التعديلات المُضافة:

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;

class LoginController extends Controller
{
  /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

  use AuthenticatesUsers;

  /**
     * Where to redirect users after login.
     *
     * @var string
     */
  protected $redirectTo = RouteServiceProvider::HOME;

  protected $username;

  /**
     * Create a new controller instance.
     *
     * @return void
     */
  public function __construct()
  {
    $this->middleware('guest')->except('logout');
    $this->username = $this->findUsername();
  }

  public function findUsername()
  {
    $login = request()->input('login');

    $fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';

    request()->merge([$fieldType => $login]);

    return $fieldType;
  }

  public function username()
  {
    return $this->username;
  }


  public function login(Request $request)
  {
    $this->validate($request, [
      'login'    => 'required|string',
      'password' => 'required|string',
    ]);

    $login_type = filter_var($request->input('login'), FILTER_VALIDATE_EMAIL)
      ? 'email'
      : 'username';

    $request->merge([
      $login_type => $request->input('login')
    ]);

    // 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.
    if (method_exists($this, 'hasTooManyLoginAttempts') &&
        $this->hasTooManyLoginAttempts($request)) {
      $this->fireLockoutEvent($request);

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

    if ($this->attemptLogin($request)) {
      return $this->sendLoginResponse($request);
    }

    // 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.
    $this->incrementLoginAttempts($request);

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

ملاحظة: هذه الطريقة مُستخدمة على إصدار 8 من لارافيل، بإستعمال الحزمة Laravel/ui

1 شخص أعجب بهذا

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة

يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن