Membuat multiple login user dengan role menggunakan middleware di Laravel

membuat-multiple-login-user-dengan-role-middleware-di-laravel

Membuat multiple login user dengan role menggunakan middleware di Laravel - Sore sobs sobs sekalian semoga pada sehat sehat semuanya, pada kesempatan kali ini gua akan menuliskan cara yang pernah atau sampai saat ini gua pake dalam menghadle kasus multi user login dengan laravel, oke sebelum mulai sobs-sobs disarankan menyiapkan kopi, melemeskan badan,  siapkan udud bagi yang udud dan tutup jendela rumah.


Langsung saja kita mulai sobs : 


1. Install Laravel, disini gua menginstall laravel via composer, sebenarnya banyak cara untuk menginstall laravel, untuk lebih tau lebih lanjut tentang cara lain proses instalasi sobs-sobs bisa kunjungi website laravel dan membaca dokumentasinya, btw disini gua pakai laravel versi 9 dan tentunya si versi 9 ini memerlukan PHP minimal versi 8.0 jika sobs sekalian PHP versinya dibawah 8 sobs sekalian bisa menyesuaikan versi laravelnya dengan PHP versi sobs sekalian.

composer create-project laravel/laravel std9

std9 adalah nama project kita, sobs-sobs bisa ganti sesuai dengan keinginan.

2. Selanjutnya masukan folder kita ke dalam text editor kesayangan sobs, disini gua pakai visual studio code. jika sudah buka file .env dan atur database sesuai dengan punya sobs sekalian.

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:Fx2+tK59NohFMClk69zyE6LEqsKRJBWYbQia/F67NUg=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=std9
DB_USERNAME=root
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=public
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
Perhatikan :
DB_CONNECTION : Jenis Database sobs sekalian disini secara default mysql, jika sobs menggunakan postgresql, oracle atau lainnya silahkan sesuaikan.
DB_HOST : alamat host database.
DB_PORT : default mysql atau mariadb adalah 3306
DB_DATABASE : nama database yang akan kita gunakan.
DB_USERNAME : user database disini default root untuk mysql dan mariadb.
DB_PASSWORD : password user database, disini kosong karena default password dari mariadb di XAMPP adalah kosong.
Jika sudah buat database sesuaikan dengan DB_DATABASE ya.

3. Selanjutnya kita buat Role model dengan file migrasinya. yaitu dengan mengetikan :

php artisan make:model Role -m

selanjutnya buka file migrasi di folder database/migrations cari file yang berisikan kata roles kenapa roles kan sebelumnya kita buat namanya Role ?? disini laravel otomatis menggenerate nama model kita ke dalam nama jamak.



ubah menjadi seperti dibawah ini :
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->id();
            // nama role
            $table->string('role_name')->unique();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('roles');
    }
};

selanjutnya buka file migrasi users


ubah menjadi seperti dibawah ini :
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            // tambahan untuk role id ditable role
            $table->unsignedBigInteger('role_id');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
};

4. Next kita buka file app/Models/Role.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    use HasFactory;

    // untuk memproteksi field id
    protected $guarded = ['id'];

    // untuk relasi one To Many
    public function users() {
        return $this->hasMany(User::class);
    }

}

5. buka file app/Models/User.php

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];


    // inverse one to Many ke tabel role
    public function role() {
        return $this->belongsTo(Role::class, 'role_id');
    }

}

6. Oke next buka file database/factories/UserFactory.php ubah menjadi seperti dibawah ini :

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
 */
class UserFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            
            // tambahkan baris diawah ini
            'role_id' => mt_rand(1, 2),

            'remember_token' => Str::random(10),
        ];
    }

    /**
     * Indicate that the model's email address should be unverified.
     *
     * @return static
     */
    public function unverified()
    {
        return $this->state(function (array $attributes) {
            return [
                'email_verified_at' => null,
            ];
        });
    }
}

7. selanjutnya kita buat data dumy dengan membuka file database/seeders/DatabaseSeeder.php dan buat seperti dibawah ini :

 
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Role;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {

        Role::create([
            'role_name' => 'superadmin',
        ]);

        Role::create([
            'role_name' => 'pegawai',
        ]);
        
        User::factory(5)->create();

    }
}
disini kita akan buat dua buah role yaitu superadmin dengan id : 1 dan pegawai dengan id : 2. dan jumlah user adalah 5 buah dengan role_id acak 1 atau 2.

8. Oke langsung saja kita migrate database kita dan kita seeding dengan mengetikan perintah : 

php artisan migrate --seed

cek database, jika berhasil migrasi maka table hasil migrasi sudah ada.


cek table roles dan users.



9. kita akan berfokus pada tampilan, silahkan buat folder layouts didalam folder resources/views.


buat file main.blade.php didalam folder layouts. tambahkan baris kode seperti dibawah ini :

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    <title>Login App</title>
  </head>
  <body>
    @yield('contents')

    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

    
  </body>
</html>
disini kita menggunakan starter kit template bootstrap 5, @yield('contents') disini lah kita membuat section konten kita, template ini berfungsi parent dari template lain pada aplikasi kita.

buat folder auth didalam folder resources/views dan buat file login.blade.php didalamnya folder auth.


tambahkan kode berikut didalam file login.blade.php :

@extends('layouts.main')

@section('contents')
    <div class="d-flex justify-content-center align-items-center vh-100">
        <div class="card" style="width: 25rem;">
            <div class="card-header text-center">
              Login
            </div>

            @if (session()->has('error'))
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
                    {{ session('error') }}
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            @endif

            <div class="card-body">
                <form method="post" action="/">
                    @csrf
                    <div class="mb-3">
                      <label for="email" class="form-label">Email</label>
                      <input type="text" name="email" class="form-control @error('email') is-invalid @enderror" id="email">
                      @error('email')
                        <div class="invalid-feedback">
                            {{ $message }}
                        </div>
                      @enderror
                    </div>
                    <div class="mb-3">
                      <label for="password" class="form-label">Password</label>
                      <input type="password" name="password" class="form-control @error('password') is-invalid @enderror" id="password">
                      @error('password')
                        <div class="invalid-feedback">
                            {{ $message }}
                        </div>
                      @enderror
                    </div>
                    
                    <button type="submit" class="btn btn-primary">Submit</button>
                </form>
            </div>
        </div>
    </div>
@endsection
Saya anggap sobs-sobs sudah paham template blade, jika kurang paham silahkan mencari refrensi ditempat lain atau mambaca dokumentasi yang disediakan laravel.

10. tahap selajutnya kita buat AuthController, controller berfungsi untuk menghandle proses autentifikasi seperti login dan logout.

php artisan make:controller AuthController

silahkan buka file AuthController didalam folder app/Http/Controllers lalu isi file sehingga akan menjadi seperti dibawah ini :

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Role;

class AuthController extends Controller
{
    public function login() {
        return view('auth.login');
    }

    public function dologin(Request $request) {
        // validasi
        $credentials = $request->validate([
            'email' => 'required|email',
            'password' => 'required'
        ]);

        if (auth()->attempt($credentials)) {

            // buat ulang session login
            $request->session()->regenerate();

            if (auth()->user()->role_id === 1) {
                // jika user superadmin
                return redirect()->intended('/superadmin');
            } else {
                // jika user pegawai
                return redirect()->intended('/pegawai');
            }
        }

        // jika email atau password salah
        // kirimkan session error
        return back()->with('error', 'email atau password salah');
    }

    public function logout(Request $request) {
        auth()->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();
        return redirect('/');
    }
}


11. Next kita akan buat dua buah controller untuk superadmin dan pegawai.

php artisan make:controller SuperadminController

nah selanjutnya controller pegawai

php artisan make:controller PegawaiController

kita buka file SuperadminController di folder app/Http/Controllers, dan ubah menjadi seperti dibawah ini :

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SuperadminController extends Controller
{
    public function index() {
        return view('superadmin.index');
    }
}

Buka PegawaiController, dan ubah menjadi seperti dibawah ini : 


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PegawaiController extends Controller
{
    public function index() {
        return view('pegawai.index');
    }
}

13. Next, kita tentukan redirect sesudah user login, artinya jika user sudah login maka si user itu tidak bisa mengakses url login atau halaman login kembali, pengaturan ini ada di app/Providers/RouteServiceProvider.php, silahkan cari const HOME ubah seperti dibawah ini :

public const HOME = '/redirect';

artinya jika user sudah melakukan login dan ingin akses kembali url login maka akan dialihkan ke url "/redirect" dan diurl redirect ini akan diperiksa apakah user yang sudah login superadmin atau pegawai, jika superadmin maka akan di redirect ke url "/superadmin" dan jika pegawai maka akan di redirect ke url "/pegawai". oleh karena itu kita buat controller yang berfungsi sebagai pengecekan terlebih dahulu. 

php artisan make:controller RedirectController

jika sudah, buka RedirectController, dan sesuaikan seperti dibawah ini :

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class RedirectController extends Controller
{
    public function cek() {
        if (auth()->user()->role_id === 1) {
            return redirect('/superadmin');
        } else {
            return redirect('/pegawai');
        }
    }
}

14. Oke sekarang kita buat masing-masing view untuk Superadmin dan Pegawai. pertama buat folder superadmin dan pegawai didalam folder resources/views, dan dimasing-masing folder superadmin dan pegawai buat file dengan nama index.blade.php. jika sudah maka akan jadi seperti dibawah ini:



buka file index.blade.php di folder superadmin dan isi seperti dibawah ini :

@extends('layouts.main')

@section('contents')
    <div class="container">
        <h2>Selamat Datang Superadmin</h2>
        <form action="/logout" method="post">
            @csrf
            <button type="submit" class="btn btn-primary">Logout</button>
        </form>
    </div>
@endsection

dan buka file index.blade.php di folder pegawai :

@section('contents')
    <div class="container">
        <h2>Selamat Datang Pegawai</h2>
        <form action="/logout" method="post">
            @csrf
            <button class="btn btn-primary" type="submit">Logout</button>
        </form>
    </div>
@endsection

15. berikutnya kita buat sebuah middleware 


php artisan make:middleware CheckRole

maka sebuah file CheckRole.php akan dibuat didalam folder app/Http/Middleware, silahkan edit file CheckRole.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class CheckRole
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next, ...$roles)
    {
        if (in_array(auth()->user()->role_id, $roles)) {
            return $next($request);
        }

        return redirect('/redirect');
    }
}

daftar middleware kita ke app/Http/Kernel.php sehingga menjadi seperti dibawah ini :


<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array<int, class-string|string>
     */
    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array<string, array<int, class-string|string>>
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array<string, class-string|string>
     */
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        // tambahkan middleware check role
        'checkrole' => \App\Http\Middleware\CheckRole::class,
    ];
}

16. Tahap akhir adalah kita tambahkan routingan aplikasi kita, lokasinya di routes/web.php :

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\RedirectController;
use App\Http\Controllers\SuperadminController;
use App\Http\Controllers\PegawaiController;

//  jika user belum login
Route::group(['middleware' => 'guest'], function() {
    Route::get('/', [AuthController::class, 'login'])->name('login');
    Route::post('/', [AuthController::class, 'dologin']);

});

// untuk superadmin dan pegawai
Route::group(['middleware' => ['auth', 'checkrole:1,2']], function() {
    Route::post('/logout', [AuthController::class, 'logout']);
    Route::get('/redirect', [RedirectController::class, 'cek']);
});


// untuk superadmin
Route::group(['middleware' => ['auth', 'checkrole:1']], function() {
    Route::get('/superadmin', [SuperadminController::class, 'index']);
});

// untuk pegawai
Route::group(['middleware' => ['auth', 'checkrole:2']], function() {
    Route::get('/pegawai', [PegawaiController::class, 'index']);

});

17. and finally silahkan jalankan aplikasi kita :

php artisan serve

sobat-sobat bisa lihat table user


silahkan login dengan email, dan untuk passwornya adalalah password karena kita menggunakan seeder. coba login dengan user role_id 1 untuk superadmin dan user role_id 2 untuk pegawai.







Aplikasi kita selesai, ahhh seruput kopinya dulu.
gua sadar sobs-sobs bahwa tulisan ini masih banyak kekurangan, jika sobs-sobs mengalami error maka sobs-sobs silahkan googling atau bertanya lewat kolom komentar.


See you next time.

22 komentar untuk "Membuat multiple login user dengan role menggunakan middleware di Laravel"

Comment Author Avatar
kok gabisa login ya padahal usernya udah ada d database
Comment Author Avatar
1. Pastikan koneksi databasenya, jika sudah
2. Coba di cek kembali di AuthController di method doLogin
Comment Author Avatar
Maaf kak, kenapa kosong gini ya kak. tidak ada ditampilkan
Comment Author Avatar
Halo Sob maksudnya kosong apaanya ya ?
Comment Author Avatar
Mohon maaf kak, redirect nya tidak bisa jalan ya, misal saya sudah login sebagai admin, tapi tiba-tiba ketik ke login lagi, harusnya kan kembali lagi ke dashboard tapi error, kenapa ya kak,padahal sudah sesuai tutorial. Terima kasih
Comment Author Avatar
Hallo gan terimakasih karena sudah berkomentar, sebelum saya typo dibagian : php artisan make:controller RedircetController
silahkan diubah nama controller menjadi RedirectController.
atau dengan artisan : php artisan make:controller RedirectController
Comment Author Avatar
halo kak, saya sudah mengikuti tutorial anda sampai habis tetapi ketika saya hendak login menggunakan email dan password yang ada di database, email atau passwordnya tetap salah. bagaimana itu?
Comment Author Avatar
Halo terimakasih sudah bertanya, coba silahkan ubah manual kembali untuk email dan passwordnya di database atau di phpmyadminnya, jika masih salah silahkan periksa kembali di AuthController di method doLogin
Comment Author Avatar
Halo kak, saya sudah mengikuti tutorial sama persis sampai habis, tetapi saya mengalami error "Target class [Illuminate\Http\Middleware\HandleCors] does not exist." Aku install Laravel 8 kok gabisa yaa?
Comment Author Avatar
Dan di file Composer.json itu php versi nya "^7.3|^8.0",
Comment Author Avatar
Terimakasih sudah bertanya, maaf slow response. error tersebut biasanya terkait dengan PHP Versinya kebetulan saya buat dengan menggunakan php versi 8.0.19.

sebagai referensi https://laracasts.com/discuss/channels/laravel/target-class-illuminatehttpmiddlewarehandlecors-does-not-exist
Comment Author Avatar
eror saat baru running webnya kaka
Comment Author Avatar
Boleh tau pesan errornya apa?
Comment Author Avatar
bang kalau saya terapkan ke laravel 11 bisa ga ya?
Comment Author Avatar
Tentunya bisa gan, cuman ada yg perlu diperhatikan seperti beberapa config terkait middleware karena diLaravel 11 ada perubahan yg signifikan terkait struktur folder dan config filenya
Comment Author Avatar
bang ini kalo mau masuk ke tampilan user pake email yang mana ya? udah saya coba yg ada di database semua ke superadmin aja
Comment Author Avatar
Kalo seperti itu coba cek dibagian middlewarenya gan
Comment Author Avatar
Halo bang, Ini punya saya error untuk masuk ke bagian superadmin maupun pegawai, nah error nya ini "Target Class [CheckRole] does not exist.
Comment Author Avatar
Padahal sudah mengikuti semua
Comment Author Avatar
Coba gan cek middleware filenya, laravel versi 11 ada sedikit perubahan
Comment Author Avatar
halo bang, untuk bikin user/akun di sqlnya input manual dari .sql ya bang? untuk itu insert intonya apa aja ya bang?
Comment Author Avatar
Bikin akun usernya bisa manual lewat sql, atau dengan menggunakan seeder dengan membuat User factory.