Providing OTP login functionality to users in laravel 11 application makes authentication easy for the user.
Here are some steps to create an authentication system using Bootstrap Authentication UI to generate, send, and verify OTP for user login:
Step 1: Set Up Bootstrap UI Auth
Run the following make ui command on cmd to install bootstrap ui auth:
cd your-laravel-application
composer require laravel/ui
php artisan ui bootstrap
php artisan ui:auth
npm install && npm run dev
Step 2: Configure SMS Provider
Edit .env
file and configure your sms service provider:
TWILIO_SID=your_twilio_sid
TWILIO_AUTH_TOKEN=your_twilio_auth_token
TWILIO_FROM=your_twilio_phone_number
Step 3: Create OTP Model and Migration
Run the following command to create otp model and migration class:
php artisan make:model Otp -m
Add some fields in the database/migrations/create_otps_table
migration file:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateOtpsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('otps', function (Blueprint $table) {
$table->id();
$table->string('mobile');
$table->string('otp');
$table->timestamp('expires_at');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('otps');
}
}
Edit the User.php
model and add the mobile
field:
protected $fillable = [
'name', 'email', 'password', 'mobile',
];
Run migration to create tables in database:
php artisan migrate
Step 4: Create OTPController
Create an OTP controller class that handles the OTP generator, send and verify operations in it:
php artisan make:controller OTPController
Add methods for sending and verifying OTP in OTPController
:
namespace App\Http\Controllers;
use App\Models\Otp;
use Illuminate\Http\Request;
use Twilio\Rest\Client;
use Carbon\Carbon;
class OTPController extends Controller
{
public function sendOtp(Request $request)
{
$request->validate([
'mobile' => 'required|digits:10'
]);
$otp = rand(100000, 999999);
$expiresAt = Carbon::now()->addMinutes(5);
Otp::updateOrCreate(
['mobile' => $request->mobile],
['otp' => $otp, 'expires_at' => $expiresAt]
);
// Send OTP via Twilio
$twilio = new Client(env('TWILIO_SID'), env('TWILIO_AUTH_TOKEN'));
$twilio->messages->create($request->mobile, [
'from' => env('TWILIO_FROM'),
'body' => 'Your OTP is ' . $otp
]);
return response()->json(['message' => 'OTP sent successfully']);
}
public function verifyOtp(Request $request)
{
$request->validate([
'mobile' => 'required|digits:10',
'otp' => 'required|digits:6'
]);
$otpRecord = Otp::where('mobile', $request->mobile)->where('otp', $request->otp)->first();
if ($otpRecord && Carbon::now()->lessThanOrEqualTo($otpRecord->expires_at)) {
$user = User::firstOrCreate(['mobile' => $request->mobile]);
Auth::login($user);
return redirect()->route('home')->with('message', 'Logged in successfully');
}
return back()->withErrors(['otp' => 'Invalid OTP or OTP expired']);
}
Step 5: Add Routes
Add routes in routes/web.php
file to handle otp generator, send and verify requests:
use App\Http\Controllers\OTPController;
Route::post('/send-otp', [OTPController::class, 'sendOtp'])->name('send.otp');
Route::post('/verify-otp', [OTPController::class, 'verifyOtp'])->name('verify.otp');
Step 6: Create OTP Views
Create a Blade view file name otp.blade.php
file in resources/views/auth/
directory to send the otp:
<!DOCTYPE html>
<html>
<head>
<title>Laravel 11 Login with OTP Example - ItcodStuff.com</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">Login with OTP</div>
<div class="card-body">
<form method="POST" action="{{ route('send.otp') }}">
@csrf
<div class="form-group">
<label for="mobile">Mobile Number</label>
<input type="text" name="mobile" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Send OTP</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
Create a Blade view file name
file in verify
.blade.phpresources/views/auth/
directory to verify the otp:
<!DOCTYPE html>
<html>
<head>
<title>Laravel 11 Verify OTP Example - itcodStuff.com</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header">Verify OTP</div>
<div class="card-body">
<form method="POST" action="{{ route('verify.otp') }}">
@csrf
<div class="form-group">
<label for="mobile">Mobile Number</label>
<input type="text" name="mobile" class="form-control" required>
</div>
<div class="form-group">
<label for="otp">OTP</label>
<input type="text" name="otp" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Verify OTP</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
Step 7: Test Application
Start the Laravel application server:
php artisan serve
Open browser and type the following url in it for testing:
http://localhost:8000/login