Kritim Yantra
Apr 08, 2025
User registration is a fundamental feature for most web applications. Laravel 12 provides an excellent authentication scaffolding system that we'll customize to create a secure, feature-rich registration page.
In this comprehensive guide, we'll cover:
composer require laravel/breeze --dev
php artisan breeze:install
npm install && npm run dev
php artisan migrate
This generates:
resources/views/auth/register.blade.php
)app/Http/Controllers/Auth
)routes/auth.php
)Check routes/web.php
now includes:
Auth::routes();
Edit resources/views/auth/register.blade.php
:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf
<!-- Name Field -->
<div class="row mb-3">
<label for="name" class="col-md-4 col-form-label text-md-end">
{{ __('Full Name') }}
</label>
<div class="col-md-6">
<input id="name" type="text"
class="form-control @error('name') is-invalid @enderror"
name="name" value="{{ old('name') }}"
required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<!-- Email Field -->
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">
{{ __('Email Address') }}
</label>
<div class="col-md-6">
<input id="email" type="email"
class="form-control @error('email') is-invalid @enderror"
name="email" value="{{ old('email') }}"
required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<!-- Password Field -->
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">
{{ __('Password') }}
</label>
<div class="col-md-6">
<input id="password" type="password"
class="form-control @error('password') is-invalid @enderror"
name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<!-- Confirm Password -->
<div class="row mb-3">
<label for="password-confirm" class="col-md-4 col-form-label text-md-end">
{{ __('Confirm Password') }}
</label>
<div class="col-md-6">
<input id="password-confirm" type="password"
class="form-control"
name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<!-- Submit Button -->
<div class="row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
First, create a migration:
php artisan make:migration add_phone_to_users_table
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->after('email')->nullable();
});
}
Run migration: php artisan migrate
Add to register.blade.php
:
<!-- Phone Field -->
<div class="row mb-3">
<label for="phone" class="col-md-4 col-form-label text-md-end">
{{ __('Phone Number') }}
</label>
<div class="col-md-6">
<input id="phone" type="tel"
class="form-control @error('phone') is-invalid @enderror"
name="phone" value="{{ old('phone') }}"
autocomplete="tel">
@error('phone')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
Edit app/Http/Controllers/Auth/RegisterController.php
:
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'phone' => ['nullable', 'string', 'max:20'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'phone' => $data['phone'],
'password' => Hash::make($data['password']),
]);
}
Add to RegisterController.php
:
use Illuminate\Validation\Rules\Password;
protected function validator(array $data)
{
return Validator::make($data, [
// ... other rules
'password' => [
'required',
'confirmed',
Password::min(8)
->mixedCase()
->numbers()
->symbols()
->uncompromised(),
],
'phone' => ['nullable', 'regex:/^([0-9\s\-\+\(\)]*)$/', 'min:10'],
]);
}
Laravel's built-in RegisterController
handles:
protected $redirectTo = '/dashboard';
)User
model:use Illuminate\Contracts\Auth\MustVerifyEmail;
class User extends Authenticatable implements MustVerifyEmail
routes/web.php
:Auth::routes(['verify' => true]);
Route::middleware(['auth', 'verified'])->group(function () {
// Protected routes here
});
php artisan vendor:publish --tag=laravel-mail
Edit resources/views/vendor/mail/html/verify-email.blade.php
// In RegisterController
protected function throttleKey(Request $request)
{
return Str::lower($request->input('email')).'|'.$request->ip();
}
<input type="text" name="honeypot" style="display:none">
Then validate:
$validator->addRules(['honeypot' => 'max:0']);
Password Hashing: Automatic with Laravel's Hash
facade
HTTPS: Ensure your form submits over HTTPS
// tests/Feature/RegistrationTest.php
public function test_registration_screen_can_be_rendered()
{
$response = $this->get('/register');
$response->assertStatus(200);
}
public function test_new_users_can_register()
{
$response = $this->post('/register', [
'name' => 'Test User',
'email' => 'test@example.com',
'password' => 'Password123!',
'password_confirmation' => 'Password123!',
]);
$this->assertAuthenticated();
$response->assertRedirect('/home');
}
Run tests: php artisan test
You've now built a secure, feature-complete registration system in Laravel 12 with:
✅ Customizable registration form
✅ Additional fields (phone number)
✅ Strong password validation
✅ Email verification
✅ Security protections
✅ Automated testing
🚀 Your application now has professional-grade user registration!
📌 Need help with specific customizations? Ask in the comments!
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google