اذهب إلى المحتوى

السؤال

Recommended Posts

  • 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 بقاعدة البيانات.

     

  • 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

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...