In this Laravel tutorial, we will learn how to create a Complete Laravel 12 Custom Login and Registration Tutorial for Beginners from scratch. While Laravel offers starter kits like Breeze and Jetstream, sometimes building a fully custom login and registration system is necessary for greater control and flexibility.
Letβs build it step by step using Laravel 12 and PHP 8.2.
Prerequisites
Make sure you have the following installed:
- PHP >= 8.2
- Composer
- MySQL
Steps for complete laravel 12 custom login and registration tutorial for beginners
- Step 1: Install Laravel 12
- Step 2: Setup Database
- Step 3: Create Authentication Controller
- Step 4: Add Routes
- Step 5: Create Views
- Step 6: Write Controller Logic
- Step 7: Create Dashboard View
- Run Laravel App:
π οΈ Step 1: Install Laravel 12
First, you need to install Laravel 12 using Composer. Run the following command:
composer create-project laravel/laravel laravel-auth-app
Move into your project folder:
cd laravel-auth-app
Step 2: Setup Database
# DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=custom_auth
DB_USERNAME=root
DB_PASSWORD=
Now run the migrations:

php artisan migrate
This will create the default users
table for authentication.
π§Ύ Step 3: Create Auth Controller
We will create a controller to manage user authentication logic.
php artisan make:controller AuthController
π§ Step 4: Create User Login & Register Routes
Open routes/web.php
and add the following routes:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
Route::get('/', function () {
return view('welcome');
});
Route::get('login', [AuthController::class, 'index'])->name('login');
Route::post('login', [AuthController::class, 'doLogin'])->name('do.login');
Route::get('registration', [AuthController::class, 'registration'])->name('register');
Route::post('registration', [AuthController::class, 'doRegistration'])->name('do.register');
Route::get('dashboard', [AuthController::class, 'dashboard']);
Route::post('logout', [AuthController::class, 'logout'])->name('logout');
π Step 5: Create Register & Login Forms
Create two Blade views:
resources/views/auth/register.blade.php
resources/views/auth/login.blade.php
Registration page preview

register.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel 12 Custom User Register Page - itstuffsolutions.io</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4Q6Gf2aSP4eDXB8Miphtr37CMZZQ5oXLH2yaXMJ2w8e2ZtHTl7GptT4jmndRuHDT" crossorigin="anonymous">
<style type="text/css">
body{
background: #F8F9FA;
}
</style>
</head>
<body>
<section class="bg-light py-3 py-md-5">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-sm-10 col-md-8 col-lg-6 col-xl-5 col-xxl-4">
<div class="card border border-light-subtle rounded-3 shadow-sm">
<div class="card-body p-3 p-md-4 p-xl-5">
<h2 class="text-center mb-4">Sign Up</h2>
<form method="POST" action="{{ route('do.register') }}">
@csrf
@if(session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@endif
<div class="row gy-2 overflow-hidden">
<div class="col-12">
<div class="form-floating mb-3">
<input type="text" class="form-control @error('name') is-invalid @enderror" name="name" placeholder="Name" required>
<label for="name" class="form-label">{{ __('Name') }}</label>
</div>
@error('name')
<span class="text-danger" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="col-12">
<div class="form-floating mb-3">
<input type="email" class="form-control @error('email') is-invalid @enderror" name="email" id="email" placeholder="example@xyz.com" required>
<label for="email" class="form-label">{{ __('Email ID') }}</label>
</div>
@error('email')
<span class="text-danger" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="col-12">
<div class="form-floating mb-3">
<input type="password" class="form-control @error('password') is-invalid @enderror" name="password" id="password" value="" placeholder="Password" required>
<label for="password" class="form-label">{{ __('Password') }}</label>
</div>
@error('password')
<span class="text-danger" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="col-12">
<div class="form-floating mb-3">
<input type="password" class="form-control @error('password_confirmation') is-invalid @enderror" name="password_confirmation" id="password_confirmation" value="" placeholder="password_confirmation" required>
<label for="password_confirmation" class="form-label">{{ __('Confirm Password') }}</label>
</div>
@error('password_confirmation')
<span class="text-danger" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="col-12">
<div class="d-grid my-3">
<button class="btn btn-dark btn-lg" type="submit">{{ __('Register') }}</button>
</div>
</div>
<div class="col-12">
<p class="text-center">Already have an account? <a href="{{ route('login') }}" class="link-dark">Login</a></p>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
Login Page preview

login.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel 12 Custom User Login Page - itstuffsolutions.io</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4Q6Gf2aSP4eDXB8Miphtr37CMZZQ5oXLH2yaXMJ2w8e2ZtHTl7GptT4jmndRuHDT" crossorigin="anonymous">
<style type="text/css">
body{
background: #F8F9FA;
}
</style>
</head>
<body>
<section class="bg-light py-3 py-md-5">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-sm-10 col-md-8 col-lg-6 col-xl-5 col-xxl-4">
<div class="card border border-light-subtle rounded-3 shadow-sm mt-5">
<div class="card-body p-3 p-md-4 p-xl-5">
<h2 class="text-center mb-4">Sign In</h2>
<form method="POST" action="{{ route('do.login') }}">
@csrf
@session('error')
<div class="alert alert-danger" role="alert">
{{ session('error') }}
</div>
@endsession
<div class="row gy-2 overflow-hidden">
<div class="col-12">
<div class="form-floating mb-3">
<input type="email" class="form-control @error('email') is-invalid @enderror" name="email" id="email" placeholder="example@xyz.com" required>
<label for="email" class="form-label">{{ __('Email ') }}</label>
</div>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="col-12">
<div class="form-floating mb-3">
<input type="password" class="form-control @error('password') is-invalid @enderror" name="password" id="password" value="" placeholder="Password" required>
<label for="password" class="form-label">{{ __('Password') }}</label>
</div>
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="col-12">
<div class="d-flex gap-2 justify-content-between">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="rememberMe" id="rememberMe">
<label class="form-check-label" for="rememberMe">Keep me logged in</label>
</div>
<a href="#">Forgot password?</a>
</div>
</div>
<div class="col-12">
<div class="d-grid my-3">
<button class="btn btn-dark btn-lg" type="submit">{{ __('Login') }}</button>
</div>
</div>
<div class="col-12">
<p class="text-center">Don't have an account? <a href="{{ route('register') }}">Sign up</a></p>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
π§ Step 6: Controller Logic
In AuthController.php
, add the following:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Session;
use App\Models\User;
use Hash;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
class AuthController extends Controller
{
/**
* Write code on Method
*
* @return response()
*/
public function index(): View
{
return view('auth.login');
}
/**
* Write code on Method
*
* @return response()
*/
public function registration(): View
{
return view('auth.register');
}
/**
* Write code on Method
*
* @return response()
*/
public function doLogin(Request $request): RedirectResponse
{
$request->validate([
'email' => 'required',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
return redirect()->intended('dashboard')
->withSuccess('You have Successfully loggedin!!');
}
return redirect("login")->withError('Oppes! Invalid credentials');
}
/**
* Write code on Method
*
* @return response()
*/
public function doRegistration(Request $request): RedirectResponse
{
$request->validate([
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:6|max:8',
]);
$data = $request->all();
$user = $this->create($data);
Auth::login($user);
return redirect("dashboard")->withSuccess('Great! You have Successfully loggedin');
}
/**
* Write code on Method
*
* @return response()
*/
public function dashboard()
{
if(Auth::check()){
return view('dashboard');
}
return redirect("login")->withSuccess('Opps! Access not allowed');
}
/**
* Write code on Method
*
* @return response()
*/
public function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password'])
]);
}
/**
* Write code on Method
*
* @return response()
*/
public function logout(): RedirectResponse
{
Session::flush();
Auth::logout();
return Redirect('login');
}
}
β Step 7: Create Dashboard View
Dashboard page preview

resources/views/dashboard.blade.php
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel 12 Custom User Dashboard - itstuffsolutions.io</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
</head>
<body>
<main>
<div class="container py-4">
<header class="pb-3 mb-4 border-bottom">
<div class="row">
<div class="col-md-1">
<a class="btn btn-dark " href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
@csrf
</form>
</div>
</div>
</header>
<div class="p-5 mb-4 bg-light rounded-3">
<div class="container-fluid py-5">
@session('success')
<div class="alert alert-success" role="alert">
{{ $value }}
</div>
@endsession
<h1 class="display-5 fw-bold">Hi, {{ auth()->user()->name }}</h1>
<p class="col-md-8 fs-4">Welcome to dashboard.<br/></p>
<button class="btn btn-dark btn-lg" type="button">Dashboard</button>
</div>
</div>
</div>
</main>
</body>
</html>
π Run Laravel App Locally
Once all the required setup steps of Complete Laravel 12 Custom Login and Registration Tutorial for Beginners have been completed, simply run the following command in your terminal:
php artisan serve
After hitting enter, Laravel’s built-in development server will start. Now, open your browser and visit the URL below to view your app:
http://localhost:8000/login
You should now see the login page of your Laravel application.
I hope this helps you get started with running your Laravel project locally!