Implement an OTP login system in Laravel 11

 


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.

Post a Comment

0 Comments