Implementing an OTP (One-Time Password) login system in Laravel 11 involves several steps, including generating OTPs, sending them to users, and verifying them during the login process. Here’s a step-by-step example:
Step 1: Set Up Laravel Project
First, set up a new Laravel project if you haven't already:
composer create-project --prefer-dist laravel/laravel:^11.0 otp-login
cd otp-login
Step 2: Create the OTP Model and Migration
Create a model and migration for storing OTPs:
php artisan make:model Otp -m
In the migration file (database/migrations/xxxx_xx_xx_create_otps_table.php
), define the schema:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateOtpsTable extends Migration
{
public function up()
{
Schema::create('otps', function (Blueprint $table) {
$table->id();
$table->string('email')->index();
$table->string('otp');
$table->timestamp('expires_at');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('otps');
}
}
Run the migration:
php artisan migrate
Step 3: Create Routes and Controllers
Define routes for OTP login in routes/web.php
:
use App\Http\Controllers\Auth\OtpController;
Route::get('otp-login', [OtpController::class, 'showLoginForm'])->name('otp.login');
Route::post('send-otp', [OtpController::class, 'sendOtp'])->name('send.otp');
Route::post('verify-otp', [OtpController::class, 'verifyOtp'])->name('verify.otp');
Create a controller for handling OTP login:
php artisan make:controller Auth/OtpController
In app/Http/Controllers/Auth/OtpController.php
, define the methods:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\Otp;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Carbon\Carbon;
class OtpController extends Controller
{
public function showLoginForm()
{
return view('auth.otp-login');
}
public function sendOtp(Request $request)
{
$request->validate([
'email' => 'required|email|exists:users,email',
]);
$otp = rand(100000, 999999);
$expiresAt = Carbon::now()->addMinutes(10);
Otp::updateOrCreate(
['email' => $request->email],
['otp' => $otp, 'expires_at' => $expiresAt]
);
// Send OTP to user's email
Mail::raw("Your OTP is: $otp", function ($message) use ($request) {
$message->to($request->email)
->subject('Your OTP Code');
});
return redirect()->route('otp.login')->with('message', 'OTP sent to your email.');
}
public function verifyOtp(Request $request)
{
$request->validate([
'email' => 'required|email|exists:otps,email',
'otp' => 'required|integer',
]);
$otpRecord = Otp::where('email', $request->email)->first();
if ($otpRecord && $otpRecord->otp == $request->otp && Carbon::now()->lessThanOrEqualTo($otpRecord->expires_at)) {
// OTP is valid
$user = User::where('email', $request->email)->first();
Auth::login($user);
// Delete OTP after successful login
$otpRecord->delete();
return redirect()->route('home');
}
return redirect()->route('otp.login')->withErrors(['otp' => 'Invalid or expired OTP.']);
}
}
Step 4: Create Views
Create the view for OTP login form in resources/views/auth/otp-login.blade.php
:
<!DOCTYPE html>
<html>
<head>
<title>OTP Login</title>
</head>
<body>
@if (session('message'))
<p>{{ session('message') }}</p>
@endif
@if ($errors->any())
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
<form action="{{ route('send.otp') }}" method="POST">
@csrf
<input type="email" name="email" placeholder="Enter your email" required>
<button type="submit">Send OTP</button>
</form>
<form action="{{ route('verify.otp') }}" method="POST">
@csrf
<input type="email" name="email" placeholder="Enter your email" required>
<input type="text" name="otp" placeholder="Enter OTP" required>
<button type="submit">Verify OTP</button>
</form>
</body>
</html>
Step 5: Configure Mail Settings
Set up your mail configuration in the .env
file to enable sending emails:
MAIL_MAILER=smtp MAIL_HOST=smtp.example.com MAIL_PORT=587 MAIL_USERNAME=your-email@example.com MAIL_PASSWORD=your-email-password MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=your-email@example.com MAIL_FROM_NAME="${APP_NAME}"
Step 6: Testing
Start your Laravel development server:
php artisan serve
Visit http://localhost:8000/otp-login
to test the OTP login functionality.
Conclusion
By following these steps, you can implement an OTP login system in Laravel 11. This approach ensures a secure way to authenticate users, especially for applications requiring enhanced security measures.
0 Comments