You can have a primary_email and an alias_email table. The relationship between a primary email and and alias_email table would be 1 to many. Login tokens would then be issued based on a check on either the primary email or related email aliases
Working with email aliases
In my application I have been experimenting with email aliases, so a user could be recognised by their main email, or, any number of aliases.
I have a model called UserEmailAlias and a model called User, there is a one to many between the two.
I have also made some helper functions:
/**
* A wrapper function to assign email aliases
*
* @param string $email
* @return void
*/
public function assignEmailAlias(string $email)
{
$this->aliases()->create(['email' => $email]);
return $this;
}
/**
* A wrapper function to remove an email alias from a user
*
* @param string $email
* @return void
*/
public function removeEmailAlias(string $email)
{
$this->aliases()->where('email', $email)->delete();
return $this;
}
Below is the source code for a controller that manages simplistic login tokens.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;
use App\UserEmailAlias;
use App\VerificationToken;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Log;
use Mail;
use App\Mail\VerifyEmail;
use App\Observers\UserEmailAliasObserver;
class TokenVerificationController extends Controller
{
/**
* Instantiate a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->email_white_list = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];
}
/**
* Display the starting form for the token authentication process
*/
public function showVerificationRequestForm()
{
return view('auth.verify');
}
/**
* Send the verification email to a valid user
*
* @return void
*/
public function sendVerificationEmail(Request $request)
{
$email = $request->get('email');
$user = User::whereIn('email', $this->email_white_list)->where('email', $request->get('email'))->first();
if ($user) {
Mail::to($user->email)->queue(new VerifyEmail($this->generateVerificationToken($user->email), $user));
} else if ($this->isAlias($email)) {
Mail::to($email)->queue(new VerifyEmail($this->generateVerificationToken($this->getUserFromAlias($email)->email), $this->getUserFromAlias($email)));
}
return back()->withSuccess('If everything worked, you\'ll recieve an email');
}
/**
* Verify the token sent back in the response
*
* @param string $token
* @return void
*/
public function verify(string $token)
{
$token = VerificationToken::where('token', $token)->first();
if ($token) {
Auth::login(User::where('email', $token->email)->first(), true);
$token->destroy();
} else {
abort(403, "There was an issue verifying your email");
}
}
/**
* Determine whether an alias exists for this email address
*
* @param string $email
* @return void
*/
private function isAlias(string $email)
{
return count(UserEmailAlias::where('email', $email)->get()) > 0 ? true : false;
}
/**
* Get the user from the alias
*
* @param string $email
* @return User
*/
private function getUserFromAlias(string $email)
{
return UserEmailAlias::where('email', $email)->first()->user;
}
/**
* Generate a token to use for authentication
*
* @param string $email
* @return string $token
*/
private function generateVerificationToken(string $email)
{
$verification_token = VerificationToken::create([
'email' => $email,
'token' => bin2hex(openssl_random_pseudo_bytes(30)),
]);
return $verification_token->token;
}
}
Is there a better way to determine whether the email entered is an alias?
I'm changing the $to address because the email either needs to go to the alias given or the actual email address.
Is it possible just to perform and join and locate the entered email address?
Please or to participate in this conversation.