In this blog post, we'll walk through how to implement a secure, token-based email unsubscribe functionality in Laravel. This method ensures that users can opt out of your emails with a single click, using unique tokens to verify their identity without exposing sensitive information. We’ll cover everything from setting up the necessary routes and controller logic to generating secure tokens in the User model and adding dynamic unsubscribe links to your email templates. By the end of this guide, you'll have a fully functional, user-friendly unsubscribe system that not only protects your users’ preferences but also enhances the credibility of your email campaigns. Let’s dive in step by step!
Step 1: Define the Unsubscribe Route
First, let’s create a route in the web.php file. We’ll use rate limiting to prevent abuse by adding a throttle middleware.
// routes/web.php
Route::middleware('throttle:10,1')->group(function () {
Route::get('/unsubscribe/{token}', [FrontEndController::class, 'unsubscribe'])->name('unsubscribe');
});
Throttle: Limits the endpoint to 10 requests per minute to prevent spam attacks.
Token: A unique identifier for the user’s unsubscribe action.
Now, let’s create the unsubscribe method in FrontEndController.php.
Step 2: Add the Unsubscribe Logic to the Controller
// app/Http/Controllers/FrontEndController.php
public function unsubscribe($token)
{
try {
$user = User::where('unsubscribe_token', $token)->first();
if (!$user || !$user->is_subscribed) {
Log::info("User with email {$user->email} is already unsubscribed or not found.");
return redirect()->route('home.homepage');
}
$user->is_subscribed = false;
$user->save();
Log::info("User with email {$user->email} successfully unsubscribed.");
return redirect()->route('home.homepage');
} catch (\Exception $e) {
Log::error("Error during unsubscribe process: " . $e->getMessage(), [
'token' => $token,
'trace' => $e->getTraceAsString(),
]);
return redirect()->route('home.homepage');
}
}
Error handling: Logs any errors and gracefully redirects users.
Safety check: Ensures users cannot unsubscribe twice.
Step 3: Generate Unsubscribe Tokens in the User Model
We need to generate a secure token for each user when sending an email. Let’s add this method to the User model.
// app/Models/User.php
public function generateUnsubscribeToken()
{
$this->unsubscribe_token = Str::random(32);
$this->unsubscribe_token_expires_at = now()->addDays(3); // Token valid for 3 days
$this->save();
}
Ensure the token is generated only if it doesn’t already exist.
if (!$user->unsubscribe_token) {
$user->generateUnsubscribeToken();
}
Step 4: Add Unsubscribe Links to Emails
Now let’s generate the unsubscribe URL and dispatch an email job
$unsubscribeUrl = route('unsubscribe', ['token' => $user->unsubscribe_token]);
DailyMorningJob::dispatch($user, $unsubscribeUrl);
The DailyMorningJob.php will handle sending the email.
public function __construct($user, $unsubscribeUrl)
{
$this->user = $user;
$this->unsubscribeUrl = $unsubscribeUrl;
}
Finally, the mail is sent with the DailyMorningMail class.
Mail::to($this->user->email)->send(new DailyMorningMail($this->user, $this->unsubscribeUrl));
DailyMorningMail.php
public $user;
public $unsubscribeUrl;
public function __construct($user, $unsubscribeUrl)
{
$this->user = $user;
$this->unsubscribeUrl = $unsubscribeUrl;
}
subject: __(
'Good Morning, :name! Begin Your Day with Wisdom',
['name' => ($this->user->name)]
)
view: 'emails.good_morning',
with: [
'userName' => $this->user->name,
'unsubscribeUrl' => $this->unsubscribeUrl,
],
Step 5: Create the Email Template
The email template includes the unsubscribe link.
<!-- resources/views/emails/good_morning.blade.php -->
<p>Hello, {{ $userName }}!</p>
@if(isset($unsubscribeUrl))
<p>If you no longer wish to receive these emails, you can <a href="{{ $unsubscribeUrl }}" style="color: #555555; text-decoration: underline;">unsubscribe here</a>.</p>
@endif
By following these steps, you can provide users with a seamless way to opt out of email subscriptions while ensuring security and efficiency. Implementing token-based unsubscribe URLs is a professional and user-friendly approach to managing email preferences.