Setting Up the Environment
First, make sure Laravel is installed. You can create a new Laravel project by running the following command:
laravel new laravel-custom-auth
Or follow the official guide in the Laravel Documentation
After downloading the project files, edit the migration file for the users table.
...
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id(); // Unique user ID
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable(); // Used to verify the user's email
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
...
Run the migration to create the users table.
php artisan migrate
Modify the User Model
Update the User model so it extends the Authenticatable class, allowing authentication features such as login and logout. Also, implement the MustVerifyEmail interface to enable email verification after registration.
User.php File
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;
class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
}
Creating the AuthController
The AuthController handles all authentication logic such as: registration, login, logout, and sending email verification links.
php artisan make:controller auth\AuthController
Here is the AuthController code with explanations:
namespace App\Http\Controllers\api;
use App\Http\Controllers\Controller;
use App\Http\Requests\LoginRequest;
use App\Http\Requests\RegisterRequest;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
class AuthController extends Controller
{
// Show registration page
public function register()
{
return view('auth.register');
}
public function register_store(RegisterRequest $request)
{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
// Log in the user
Auth::login($user);
// Send verification email
$user->sendEmailVerificationNotification();
// Redirect to profile page
return redirect()->route('profile')
->with('success', 'Registration successful! Welcome.');
}
// Show login page
public function login(Request $request)
{
return view('auth.login');
}
public function login_store(LoginRequest $request)
{
// Attempt login using email and password
if (Auth::attempt($request->only('email', 'password'))) {
// Regenerate session for security
$request->session()->regenerate();
return redirect()->route('profile')
->with('success', 'Login successful! Welcome.');
}
// Invalid credentials
return back()->withErrors([
'email' => 'The provided credentials are incorrect.',
])->onlyInput('email');
}
public function logout()
{
// Logout user
Auth::logout();
// Redirect to homepage
return redirect()->route('home')
->with('success', 'You have been logged out successfully.');
}
}
Creating LoginRequest and RegisterRequest
These request classes validate user input before saving data into the database.
RegisterRequest File
php artisan make:request RegisterRequest
The RegisterRequest file will be located at:
App\Http\Requests\RegisterRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'name' => 'required|string|min:2|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:6',
'password_confirmation' => 'required|string|min:6|same:password',
];
}
public function messages(): array
{
return [
'name.required' => 'The name field is required.',
'email.required' => 'The email field is required.',
'email.email' => 'Please provide a valid email address.',
'email.unique' => 'This email is already registered.',
'password.required' => 'The password field is required.',
'password.min' => 'The password must be at least 6 characters long.',
'password.confirmed' => 'The password confirmation does not match.',
];
}
}
LoginRequest File
php artisan make:request LoginRequest
The LoginRequest file will be located at:
App\Http\Requests\LoginRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class LoginRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'email' => 'required|email',
'password' => 'required|min:6',
];
}
public function messages()
{
return [
'email.required' => 'Email is required.',
'email.email' => 'Please provide a valid email address.',
'password.required' => 'Password is required.',
'password.min' => 'Password must be at least 6 characters long.',
];
}
}
Defining Routes
routes\web.php
use App\Http\Controllers\api\AuthController;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Auth\EmailVerificationRequest;
Route::view("/", "welcome")->name("home");
Route::get('/login', [AuthController::class , 'login'])->name('login');
Route::post('/login', [AuthController::class , 'login_store'])->name('login.store');
Route::get('/register', [AuthController::class , 'register'])->name('register');
Route::post('/register', [AuthController::class , 'register_store'])->name('register.store');
Route::post('/logout', [AuthController::class , 'logout'])
->name('logout')
->middleware('auth');
Route::view('/profile', "auth.profile")
->name('profile')
->middleware('auth');
// Email Verification Routes
Route::view('/email/verify', "auth.verify-email")
->middleware('auth')
->name('verification.notice');
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
$request->fulfill();
return redirect('/profile');
})->middleware(['auth', 'signed'])
->name('verification.verify');
Route::post('/email/verification-notification', function (Illuminate\Http\Request $request) {
$request->user()->sendEmailVerificationNotification();
return back()->with('message', 'Verification email sent!');
})->middleware(['auth', 'throttle:6,1'])
->name('verification.resend');
Views Files resources\views
All view files are attached to this article and can be downloaded from Here
If you have any questions, leave them in the comments section or contact us