Pada kisah sebelumnya saya sebenarnya ingin mencari konfigurasi multiple authentication. Tapi malah nyasar ke token authentication.

Dengan multi-auth ini kita bisa membuat fitur login dengan table yang berbeda-beda dengan lebih mudah. Misalnya ada table dokter, pasien, dan staff.

Di Laravel 4, anda bisa menggunakan ollieread/multiauth untuk menggunakan multiple auth. Atau Kbwebs/MultiAuth untuk Laravel 5.0 dan 5.1.

Tetapi pada Laravel 5.2, Taylor Otwell menambahkan fitur ini ke core Laravel

So, gimana cara menggunakan multiple auth ini? Sangat mudah, tidak jauh berbeda dengan dua kisah sebelumnya. Kita bisa baca informasi pada config/auth.php

Screen Shot 2015-12-18 at 22.00.12

Jadi kita cukup menambahkan guards dan providers.

Persiapan

Contoh misalnya kita ingin ada tiga jenis user:

  • Doctor
  • Patient
  • Staff

Buat model yang mirip dengan app/User.php. Kita bisa copy dan edit nama class-nya. Jangan lupa buat juga  migrations untuk model tersebut. Isinya bisa copy dari /database/migrations/2014_10_12_000000_create_users_table.php, atau anda bisa buat sendiri sesuai dengan kebutuhan.

Setelah itu edit config/auth.php, tambahkan tiga guards dan tiga providers baru.

'guards' =>  [
    'doctor' =>  [
        'driver'   => 'session',
        'provider' => 'doctor',
    ],

    'patient' =>  [
        'driver'   => 'session',
        'provider' => 'patient',
    ],

    'staff' =>  [
        'driver'   => 'session',
        'provider' => 'staff',
    ],
],

// ... 

'providers' =>  [
    'doctor' =>  [
        'driver' => 'eloquent',
        'model'  => App\Doctor::class,
    ],

    'patient' =>  [
        'driver' => 'eloquent',
        'model'  => App\Patient::class,
    ],

    'staff' =>  [
        'driver' => 'eloquent',
        'model'  => App\Staff::class,
    ],
],

Login

Persiapan selesai. Saatnya simulasi untuk login. Eits, jangan lupa tambahkan user pada masing-masing model.

Berikut adalah file app/Http/routes.php

Route::get('/login', function() {

    $auth = auth()->guard('doctor'); // Atau \Auth::guard('doctor')

    $credentials = [
        'nip' =>  '04324321', // Nomor Induk Pegawai
        'password' =>  'sate',
    ];

    if ($auth->attempt($credentials)) {
        return 'Yay! Berhasil login (^o^)/';
    }

    return 'Gagal login.';

});

Well done 😀

UPDATE 19 Jan 2016 23:33:56

Pada Laravel 5.2 terbaru, tepatnya 5.2.10, kita bisa gunakan

auth('doctor')

lebih singkat daripada

auth()->guard('doctor')

Detailnya bisa dilihat di https://github.com/laravel/framework/commit/2edaa2791317e1ff0cf80a5d8539e983154082c1.

UPDATE 18 Maret 2016 08:26

Source code demo bisa dilihat di https://github.com/mul14/laravel-52-multiple-auth-demo

Iklan

52 pemikiran pada “Multiple Authentication di Laravel 5.2

      1. Lha?? Ya itu udah table berbeda. Coba dibaca ulang dan perhatikan providers. Disitu kan model-nya beda-beda. Kalau model beda, table-nya beda juga gak? :/

      1. Yaa nggak harus. Tergantung aja anda mau bikin gimana.

        Misalnya, saya mau bikin ada opsi untuk memilih level

        <input type="text" name="username">
        <input type="password" name="password">
        <select name="level">
          <option>customer</option>
          <option>admin</option>
        </select>

        Atau saya cuma mau share view doank, bisa juga.

        // app/Http/Controllers/AdminAuthController.php
        // ...
        public function getLogin()
        {
            return view('auth/login'); // View yang sama.
        }
        
        // app/Http/Controllers/CustomerAuthController.php
        // ...
        public function getLogin()
        {
            return view('auth/login'); // View yang sama.
        }
        

        Atau lagi, misalnya saya cuma mau di url, kalau admin memasukkan ?level=admin

        // app/Http/Controllers/AuthController.php
        // ...
        public function postLogin()
        {
            $guard = '';
        
            if (request()->has('level') == 'admin') {
                $guard = 'admin';
            }
        
            auth($guard)->attempt(request()->only('username', 'password')); 
            // dst dst...
        }
        

        Mau dibikin gimana yaa tergantung kita sendiri.

  1. om, kalau mohon maaf ni, kurang jelas di bagian awal “Buat model yang mirip dengan app/User.php. Kita bisa copy dan edit nama class-nya. Jangan lupa buat juga migrations untuk model tersebut. Isinya bisa copy dari /database/migrations/2014_10_12_000000_create_users_table.php, atau anda bisa buat sendiri sesuai dengan kebutuhan.”
    yang semacam app/user.php ini isi nya yang berbeda hanya di array $fillable kan ?
    dan yang migrations itu wajib buat ya om ?

    ane cuma mau ganti tabel nya doank, yang ane ganti semua yang namanya users dengan nama tabel baru di file auth.php
    tapi kok masih request login nya masih dari tabel users
    mohon bimbingan nya hehe

    1. Buat model yang mirip dengan app/User.php. Kita bisa copy dan edit nama class-nya

      Maksudnya isinya sama, hanya beda nama class. Misalnya nih app/User.php sama dengan app/Admin.php, berarti tinggal copy aja

      cp app/User.php app/Admin.php

      Karena Laravel menggunakan PSR-4, jadi nama file dan nama class harus sama. Kalau hasil copy kan isinya masih equivalent, makanya diubah nama class-nya.

      Misalnya app/User.php isinya adalah,

      class User extends Authenticable
      {
      // ...
      }

      Yaa diganti donk kalau app/Admin.php

      class Admin extends Authenticable
      {
      // ...
      }

      … yang semacam app/user.php ini isi nya yang berbeda hanya di array $fillable kan ?

      Ini tergantung dari table yang dibikin. Misalnya admin nggak perlu birthday, yaa nggak usah ada birthday di table admins. Jadi $fillable dikurangi birthday.

      Tapi kalau ternyata table users dan admins itu sama kebutuhannya… sama-sama butuh username, sama-sama butuh password, sama-sama butuh email, dst… yaa $fillable kan jadi sama pada kedua model.

      migrations itu wajib buat ya om?

      Gak wajib. Migrations untuk mempermudah aja. Detail dari manfaat migrations bisa dipelajari dari berbagai sumber, salah satunya ini http://www.iheavy.com/2011/06/15/database-migration-what-is-it-and-why-is-it-important/

      ane cuma mau ganti tabel nya doank, yang ane ganti semua yang namanya users dengan nama tabel baru di file auth.php
      tapi kok masih request login nya masih dari tabel users

      Coba pelajari source code yang sudah diberikan https://github.com/laravel/framework/commit/2edaa2791317e1ff0cf80a5d8539e983154082c1

  2. bang mul, kan udah bisa tiap user login, cuman seandainya kasusnya, ane bikin 3 level user, trus bikin masing masing login sendiri, nah validasinya per Auth::guard() -nya gimana ya,
    misal Auth::guard(‘dokter’) hanya bisa akses pagenya dia,
    dan Auth::guard(‘pasien’) hanya bisa akses pagenya dia.

    bisa gak bang, validasi Auth::guard dalam middleware, jadi tiap route sudah di middleware pake validasi tadi.

    1. Hoo, ya bisa. Kalau kasusnya sederhana, default middleware bawaan Laravel juga sudah cukup.

      Misalnya middleware diletakkan di `app/Http/routes.php`

      Route::group(['middleware' => 'auth:doctor'], function () {
      // disini tidak akan bisa diakses oleh yang bukan doctor.
      });
      

      Atau bisa juga di Controller

      class DoctorOnlyController extends Controller 
      {
          public function __construct()
          {
              $this->middleware('auth:doctor');
          }
      }
      

      Detailnya bisa baca post sebelumnya https://mul14.wordpress.com/2015/05/17/laravel-access-control/

      Atau baca dokumentasi Laravel tentang middleware.

      1. gitu bang, oh ya, masalah efektifitasnya mana bang 1 ato 2, soalnya middleware bisa di pakai selain untuk validasi auth::?
        sebelumnya makasi bang

  3. Terima kasih mas, infonya sangat membantu.

    Lalu untuk membuat fungsi login (session, remember password, dsbnya) gmn ya? apakah diintegrasikan dgn login bawaan Laravel? mungkin bisa kasih sedikit gambaran/info hehe

      1. iya mas,
        saya coba buat auth controller baru dengan fungsi login
        Auth::guard(’employee’)->attempt() dst nya disamain ke yg bawaan laravel, login berhasil.

        tapi kok pas saya bikin middleware, lalu cek Auth::guard(’employee’)->check() isinya kosong ya (false)?

  4. Om, kalau defaultnya Auth::user()->name untuk menampilkan field name di table users. Nah misalkan kita mau custom/multi table seperti diatas jadinya gimana ya?

    1. Yaa sama aja, hanya ditambahin guard. Misalnya

      // Pakai helper
      auth('admin')->user()->name;
      auth()->guard('admin')->user()->name;
      
      // Pakai facade
      Auth::guard('admin')->user()->name;
      
  5. om.. ane udah nerapin yg kayak gitu tp ada kendala…
    pas login udah berhasil ( Auth::guard(‘user’)->attempt($credentials) ) ==> return true

    tp pas di redirect ke halaman home malah di redirect lg ke halaman login. itu gmn ya letak kesalahannya?

    nb:
    route
    Route::group([‘middleware’ => ‘web’], function () {
    Route::auth();
    Route::get(‘/’, [‘as’ => ‘dashboard’, ‘uses’ => ‘HomeController@index’]);
    Route::get(‘/home’, [‘as’ => ‘home’, ‘uses’ => ‘HomeController@index’]);
    });

    1. Biasanya di HomeController itu ada di-set auth middleware. Yang mana, middleware-nya itu cuma ngecek default guard.

      Solusinya tambahin aja di middleware pada HomeController.

      class HomeController extends Controller
      {
          public function __construct()
          {
              $this->middleware('auth:doctor');
              $this->middleware('auth:patient');
              $this->middleware('auth:staff');
          }
      }
      
  6. mas @mul14 : saya berhasil mengikuti langkah diatas. ketika saya buat login admin.
    untuk validation ga work, kalau route admin diletakkan di dalam route group admin.
    jika saya letakkan route di luar route admin, validation work.
    solusinya gmn mas mul, kalau route ingin diletakkan didalam route group, karena
    berhubungan dengan ACL. Thank`s

    AdminController.php:

    public function login()
    {
    return view(‘admin.login’);
    }
    public function postlogin(Request $request)
    {
    $validator = validator( $request->all(), [
    ’email’ => ‘required|min:6|max:10’,
    ‘password’ => ‘required|min:6|max:10’,
    ]);
    if ($validator->fails()) {
    return redirect(‘admin/login’)
    ->withErrors($validator)
    ->withInput();
    }
    }

    di route.php :

    Route::group([‘middleware’ => ‘admin’], function () {
    Route::get(‘/admin’, ‘AdminController@index’);
    Route::get(‘/admin/login’, ‘AdminController@login’);
    Route::post(‘/admin/login’, ‘AdminController@postlogin’);
    });

  7. Mas Mul, itu kan login formnya beda2 ya?
    Dokter login di “/login/doctor” dan pasien login di “login/patient”

    Biar loginnya di satu tempat saja bisa gk mas? misalnya di “/login”

    Makasih…

    1. Ya bisa donk Itu cuma pakai logika sederhana aja. Misalnya,

      (1)

      <form method="post" action="/login">
        <input type="text">
        <input type="password">
        <button type="submit" name="submit" value="patient">Login as Patient</button>
        <button type="submit" name="submit" value="doctor">Login as Doctor</button>
      </form>

      Nanti di backend tinggal tambahin

      if (request()->submit == 'patient') {
          // Login sebagai pasien
      }
      
      if (request()->submit == 'doctor') {
          // Login sebagai dokter
      }

      (2) Mau pakai JavaScript untuk ganti isi atribute action pada <form> bisa.

      (3) Mau pakai <select> juga bisa.

      (4) Atau format username menjadi pembeda juga bisa,

      // Jika username "p-98765"
      if (preg_match('/^p.+/', request()->username)) { 
          // Login sebagai pasien
      }
      
      // Jika username "doc-12345"
      if (preg_match('/^doc.+/', request()->username)) { 
          // Login sebagai dokter
      }

      Tinggal di-explore aja sesuai kebutuhan.

  8. Mas, implementasi real’nya gimana ya, maksudnya lebih ke contoh kasus.
    Saya pikir kasus diatas bisa di handle sma ACL biasa.
    contoh aplikasi seperti apa yang pake multiauth & contoh aplikasi seperti apa yang pake ACL

    1. Yaa bikin if sederhana aja. Deteksi itu username atau email. Kan bisa ketahuan kalau email ada tanda @. Misalnya bisa pake strpos, preg_match, filter_var, atau apapun.

  9. Hallo om, mau tanya nih.. saya sukses bikin multiauth dengan custom guard dan sukses login / register user baru dengan table baru “customers” .
    yang mau sy tanya : kenapa status guest nya tetap aktif ketika sudah login customer?

    view(layouts.app)
    
    @if (Auth::guest()) 
        <a href="{{ url('store/customer/login') }}" rel="nofollow">Login</a>
        <a href="{{ url('store/customer/register') }}" rel="nofollow">Register</a>
    @elseif(auth()->guard('customer')->check())
    
    <a href="#" rel="nofollow">
        {{  auth()->guard('customer')->user()->name }}  
    </a>
    
    <a href="{{ url('/store/logout') }}" rel="nofollow"><i></i>Logout</a>
    

    ketika menuju routes yang tdk ditentukan auth nya (contoh: halaman umum catalog produk), tombol login & register kembali muncul padahal sudah login (kenapa status guest check: true).. salahnya dimana ya? terimakasih sebelumnya

    NB: jika multi auth menggunakan table users (default) / tdk menggunakan table customers, masalah diatas ga terjadi

    1. Coba begini

      @if (auth('customer')->guest())
      

      Atau, dibalik saja

      @if (auth()->guard('customer')->check())
      Username / Logout
      @else
      Login / Register
      @endif
      
      1. makasih om, button login / register solved 😀
        tp masih dalam uneg2 pertanyaan dalam hati, kenapa status guestnya tetap masih true ya om? (Auth::guest()->check()), sedangkan klo login menggunakan table users bawaan, status guestnya false?
        😕

Tinggalkan Balasan

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s