PHPackages                             laragear/email-login - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. laragear/email-login

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

laragear/email-login
====================

Authenticate users through their email in 1 minute.

v4.0.0(2mo ago)948MITPHPPHP ^8.3CI passing

Since Sep 9Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/Laragear/EmailLogin)[ Packagist](https://packagist.org/packages/laragear/email-login)[ Fund](https://github.com/sponsors/DarkGhostHunter)[ Fund](https://paypal.me/darkghosthunter)[ RSS](/packages/laragear-email-login/feed)WikiDiscussions 4.x Synced 1mo ago

READMEChangelog (8)Dependencies (17)Versions (14)Used By (0)

Email Login
===========

[](#email-login)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d4b5c1bff1821eddb98c22c6c14014a971edd05471f38c55f53f7c2e578bba2b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c617261676561722f656d61696c2d6c6f67696e2e737667)](https://packagist.org/packages/laragear/email-login)[![Latest stable test run](https://github.com/Laragear/EmailLogin/workflows/Tests/badge.svg)](https://github.com/Laragear/EmailLogin/actions)[![Codecov coverage](https://camo.githubusercontent.com/26a00b86b63a57b3fc7f043880f705e944abe885b93bbec1a43c9321bc71ec82/68747470733a2f2f636f6465636f762e696f2f67682f4c617261676561722f456d61696c4c6f67696e2f67726170682f62616467652e7376673f746f6b656e3d4e66723863416c467643)](https://codecov.io/gh/Laragear/EmailLogin)[![Maintainability](https://camo.githubusercontent.com/2bdc4d3f251942760cda8af3499d80d1318f04ee6f8bab30f2fa10f988a8104f/68747470733a2f2f716c74792e73682f6261646765732f38643964373437392d616136652d343063652d613233632d6237393462633962393866382f6d61696e7461696e6162696c6974792e737667)](https://qlty.sh/gh/Laragear/projects/EmailLogin)[![Sonarcloud Status](https://camo.githubusercontent.com/6989183d8603140ff987db2986629b05c830a9eb7b505239acd146f6c9b06c44/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4c617261676561725f456d61696c4c6f67696e266d65747269633d616c6572745f737461747573)](https://sonarcloud.io/dashboard?id=Laragear_EmailLogin)[![Laravel Octane Compatibility](https://camo.githubusercontent.com/70359a356da237cd29561bc5d0bb80baae775b5ff62f288ed324755382858342/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2532304f6374616e652d436f6d70617469626c652d737563636573733f7374796c653d666c6174266c6f676f3d6c61726176656c)](https://laravel.com/docs/13.x/octane#introduction)

Authenticate users through their email in 1 minute.

```

    @csrf

    Log in

```

Keep this package free
----------------------

[](#keep-this-package-free)

[![](.github/assets/support.png)](https://github.com/sponsors/DarkGhostHunter)

Your support allows me to keep this package free, up-to-date and maintainable. Alternatively, you can **spread the word on social media**

Requirements
------------

[](#requirements)

- PHP 8.3 or later
- Laravel 12 or later

Installation
------------

[](#installation)

Then call Composer to retrieve the package.

```
composer require laragear/email-login
```

1 minute quickstart
-------------------

[](#1-minute-quickstart)

Email Login is *very simple* to use: put the email of the user you want to authenticate in a form, and an email will be sent to him with a single-time link to authenticate.

First, install the configuration file and the base the controllers using the `email-login:install` Artisan command.

```
php artisan email-login:install
```

After that, ensure you register the routes that the login email will use for authentication using the included route registrar helper at `Laragear\EmailLogin\Http\Routes` class.

```
use Illuminate\Routing\Route;
use Laragear\EmailLogin\Http\Routes as EmailLoginRoutes;

Route::view('welcome');

// Register the default Mail Login routes
EmailLoginRoutes::register();
```

Tip

You may change the route path for the email login as an argument, additionally to the controller.

```
use Laragear\EmailLogin\Http\Routes as EmailLoginRoutes;

EmailLoginRoutes::register(
    send: '/send-email-here',
    login: '/login-from-email-here',
    controller: 'App/Http/Controllers/MyEmailLoginController',
);
```

Finally, add a "login" box that receives the user email by making a `POST` to `auth/email`, anywhere in your application.

```

    @csrf

    Log in

```

That's it, your user is ready to log in with its email.

This package will handle the whole logic for you, but you can always go full manual with your own routes and controllers.

Sending the login email
-----------------------

[](#sending-the-login-email)

To implement the login email manually, you need to capture the email from the form submission, using the Form Request and the Login Builder.

- The `Laragear\EmailLogin\Http\Requests\EmailLoginRequest` it's a great way to handle the request and build the Login Email while validating the data, all at once.
- the `Laragear\EmailLogin\EmailLoginBuilder` is the object responsible for building the Login Email the `EmailLoginRequest` uses behind the scenes and can be used for custom authorization.

If you're using the defaults that come with Laravel, using the included Form Request class will automatically validate the email. You only need to return the `sendAndBack()` method to redirect the user back to the form.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->sendAndBack();
});
```

You can also use `send()` and `back()` separately if you need to do something before sending the email, and use the `validate()` method if you want to expand on the validation procedure.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    $email->validate([
        'email' => 'required|email:rfc,dns'
    ]);

    $email->withExpiration(30)->send();

    session()->flash('message', 'Check your email in a few seconds.');

    return back();
});
```

Both `sendAndBack()` and `send()` return `true` if the user with the credentials is found and the email is sent (or queued to be sent), and `false` if the user doesn't exist. Some apps will be fine by obfuscating the user existence, but some may want to show if the user doesn't exist.

```
if ($email->send()) {
    session()->flash('message', 'Email sent successfully!');
} else {
    throw ValidationException::withMessages([
        'email' => 'The user with the email does not exist'
    ]);
}
```

### Custom credentials

[](#custom-credentials)

When sending an Email Login, the validated data is used to find the user to be authenticated through the User Provider of the Guard. For example, if you validate the `username` key, only that will be used to find the user and send the email.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    $email->validate([
        'username' => 'required|string|exists:users'
    ]);

    return $email->sendAndBack();
});
```

You can override the credentials to find the user using the `withCredentials()` method with a list of the keys in the request input that should be used as credentials. The list may be different from the validated request input.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    $email->validate([
        // ...
    ]);

    return $email->withCredentials(['username', 'mail'])->sendAndBack();
});
```

Keys can also be callbacks that receive the query to find the User.

```
$email->withCredentials([
    'mail',
    fn($query) => $query->where('is_human', '>', 0.5)
]);
```

Alternatively, if you issue a key-value pair, the value of the key will be used as a credential value.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    $email->validate([
        'email' => 'required|email'
    ]);

    return $email->withCredentials([
        'mail' => $email->email,
        'banned_at' => null,
        fn($query) => $query->where('standing', '>', 0.5)
    ])->sendAndBack();
});
```

### Login expiration

[](#login-expiration)

The link to login sent in the email has an expiration time, which by default is 5 minutes. You can change this globally through the [configuration](#link-expiration) or at runtime using the `withExpiration()` with either the number of minutes, a `DateTimeInterface` instance, or a string to be passed to [`strtotime()`](https://www.php.net/manual/function.strtotime.php).

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withExpiration(10)->sendAndBack();
});
```

### Custom remember key

[](#custom-remember-key)

If your request has the `remember` key, and it's *truthy*, the user will be remembered into the application when he logs in. If the key is different, you may set a string with the key name through the `withRemember()` method.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withRemember('remember_me')->sendAndBack();
});
```

Alternatively, issuing anything else will be used as the condition, like a boolean or a callback.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withRemember(fn() => $email->remember_me === 'on'))->sendAndBack();
});
```

### Specifying the guard

[](#specifying-the-guard)

By default, the Email Login assumes the user will authenticate using the default guard, which in most *vanilla* Laravel applications is `web`. You may want to change the [default guard in the configuration](#guard), or change it at runtime using `withGuard()`:

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/admin/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withGuard('admin')->sendAndBack();
});
```

### Email URL link

[](#email-url-link)

You may change the URL where the Email Login will point to through the [configuration](#route-name--view), or at runtime using the `withPath()`, `withQuery()`, `withAction()`, and `withRoute()` methods. You may set also parameters using an array as a second argument, if you need to.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withRoute('auth.email.login', ['is_cool' => true])->sendAndBack();
});
```

Note

The `withPath()` doesn't support query parameters (by Laravel convention), extra parameters will be added as paths like `foo/bar/baz`. To set a query, use the other methods.

You may also only append extra parameters to the default URL set in the configuration using `withParameters()` method.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withParameters(['is_cool' => true])->sendAndBack();
});
```

Warning

The route **must** exist. This route should show a form to login, **not** login the user immediately. See [Login in from an email](#login-in-from-an-email).

### Customizing the Mailable

[](#customizing-the-mailable)

The most basic approach to use your own [Mailable](https://laravel.com/docs/11.x/mail#generating-mailables) class is to set it through the `withMailable()` method, either as a class name (instanced by the Container) or object instance.

```
use App\Mails\MyLoginMailable;
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withMailable(MyLoginMailable::class)->sendAndBack();
});
```

Alternatively, you may want to use callback to customize the included Mailable instance. The callback receives the `LoginEmail` mailable. Inside the callback you're free to modify the mailable to your liking, like changing the view or the destination, or even return a new Mailable altogether.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;
use Laragear\EmailLogin\Mails\LoginEmail;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withMailable(function (LoginEmail $mailable) {
        $mailable->view('my-login-email', ['theme' => 'blue']);

        $mailable->subject('Login to this awesome app');
    })->sendAndBack();
});
```

### Opaque throttling

[](#opaque-throttling)

If you want to throttle sending the email *opaquely*, use the `withThrottle()` method with the amount of seconds. During that time, the email will not be sent. This is great to avoid a massive number of emails being resent.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withThrottle(30)->sendAndReturnBack();
});
```

The throttling uses the same cache used to store the email login intent, and the request fingerprint (IP) by default. You may change the cache store with the second argument, and even the key to use as throttler identifier as the third argument.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    $key = strtolower($email->input('email'));

    return $email->withThrottle(30, 'redis', $key)->sendAndReturnBack();
});
```

> \[!WARN\]
>
> Throttling requires the Request fingerprint, which is unavailable when a Request is not attached to a route, like using Laravel Livewire components. In these cases, a key is required.

### Adding metadata

[](#adding-metadata)

You can save data that's valid only for the login attempt using the `withMetadata()` method. You may set here an array of keys and values that you can [later retrieve](#retrieving-metadata) when the login is successful.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;
use Laragear\EmailLogin\Http\Requests\LoginByEmailRequest;

// Send the email and save the metadata internally.
Route::post('/auth/email/send', function (EmailLoginRequest $request) {
    return $request
        ->withMetadata(['is_cool' => true])
        ->sendAndReturnBack();
});

// Show the login form with the metadata.
Route::get('/auth/email/login', function (LoginByEmailRequest $request) {
    return view('laragear::email-login.web.login', [
        'is_cool' => $request->metadata('is_cool')
    ]);
});
```

Tip

The metadata is not transmitted in the email link but stored as part of the Email Login Intent inside your application cache.

Login in from an Email
----------------------

[](#login-in-from-an-email)

The login procedure from an email must be done in two controller actions: one showing a form, and another authenticating the user. Both of these routes should use the `guest` middleware to avoid being hit by an authenticated user.

Warning

The Log In must be done in two controller actions because **some email clients and servers will preload, cache and/or prefetch the login link**. While this is usually done to speed up navigation or filter malicious sites, this will accidentally log in the user outside its device, and render further login attempts unsuccessful.

To avoid this accidental authentication, make a route that shows a form to login and another to authenticate the user.

Use the `Laragear\Http\Requests\LoginByEmailRequest` Form Request to return the view with the form to login, and to log in the user, on both users.

- When the login is invalid or expired, an HTTP 419 (Expired) error is shown to the user instead of the view. Otherwise, you may use the included `laragear::email-login.web.login` view to show the form.
- When receiving the login form submission, the user will be automatically logged in.

```
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\LoginByEmailRequest;

Route::middleware('guest')->group(function () {
    // Show the form to log in.
    Route::get('/auth/login/mail', function (LoginByEmailRequest $request) {
        return view('laragear::email-login.web.login');
    })->name('login.mail');

    // User logged in automatically, show him the dashboard.
    Route::post('/auth/login/mail', function (LoginByEmailRequest $request) {
        return $request->toIntended();
    });
})
```

### Retrieving metadata

[](#retrieving-metadata)

If you have [set metadata before sending the email](#adding-metadata), you can retrieve it using the `metadata()` method along with the key in `dot.notation`, and optionally a default value if it's not set.

```
use Laragear\EmailLogin\Http\Requests\LoginByEmailRequest;
use Illuminate\Support\Facades\Route;

Route::get('auth/login/mail', function (LoginByEmailRequest $request) {
    return view('laragear::email-login.web.login', [
        'is_cool' => $request->metadata('is_cool');
    ]);
});
```

Email Login Broker
------------------

[](#email-login-broker)

If you want a more *manual* way to log in the user, use the `EmailLoginBroker`, which is what the Form Request helpers use behind the scenes.

To create an Email Login Intent, use the `create()`. It requires the authentication guard, the user ID and an expiration time. It returns a random token that should be used to transmit via Email.

```
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\EmailLoginBroker;use Laragear\EmailLogin\Mails\LoginEmail;

Route::post('/send-login-email', function (Request $request, EmailLoginBroker $broker) {
    $request->validate([
        'email' => 'required|email'
    ]);

    // Find the user by its email
    $user = User::where('email', $request->email)->first();

    // Send the email if the user exists.
    if ($user) {
        $url = url('/login-by-email', [
            'token' => $broker->create('web', $user->id),
            'guard' => 'web',
        ]);

        // Send the email with the url to the user.
        LoginEmail::make($user, $url)->to($request->email)->send();
    }

    session()->flash('message', 'Login email sent successfully!');

    return back();
});
```

After the user is redirected to your email login form, use the `get()` method with the token to retrieve the `EmailLoginIntent`.

```
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\EmailLoginBroker;use Laragear\EmailLogin\Mails\LoginEmail;

Route::get('/login-by-email', function (Request $request, EmailLoginBroker $broker) {
    // If the intent exists, show him the login form.
    if ($broker->get($request->query('token'))) {
        return view('my-email-login-view');
    }

    // If it doesn't exist, redirect the user back to the initial login.
    return redirect('send-login-email');
});
```

Once the form submission is received, use the `pull()` method to remove the intent from the cache store and log in the user using the `EmailLoginIntent` instance data.

```
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Laragear\EmailLogin\EmailLoginBroker;

Route::post('/login-by-email', function (Request $request, EmailLoginBroker $broker) {
    $intent = $broker->pull($request->query('token'));

    // If the intent doesn't exist, bail out.
    if (!$intent) {
        return redirect('send-login-email');
    }

    // Log in the user using the intent data.
    Auth::guard($intent->guard)->loginUsingId($intent->id, $intent->remember);

    // Regenerate the session for security.
    $request->session()->regenerate();

    return redirect('/dashboard');
});
```

Custom token string
-------------------

[](#custom-token-string)

When generating the email login token, a random ULID will be generated. You may change the default generator by setting a callback that receives the `EmailLoginIntent` and returns a (hopefully very) random string. You may do this in your `AppServiceProvider::register()`.

```
use Illuminate\Support\Str;
use Laragear\EmailLogin\EmailLoginBroker;
use Laragear\EmailLogin\EmailLoginIntent;

public function register()
{
    EmailLoginBroker::$tokenGenerator = function (EmailLoginIntent $intent) {
        return Str::random(128);
    };
}
```

### Custom Email Broker Store

[](#custom-email-broker-store)

You may define a custom cache store to store the token at runtime, using the `withStore()` method. The method should receive the name of the cache store available in your application.

```
use Illuminate\Support\Facades\Route;
use Laragear\EmailLogin\Http\Requests\EmailLoginRequest;

Route::post('/auth/email/send', function (EmailLoginRequest $email) {
    return $email->withStore('valkey-persistent')->sendAndReturnBack();
});
```

Note

The cache store is always set in the login link, which will instruct the Email Login Broker where to look for the token.

Advanced Configuration
----------------------

[](#advanced-configuration)

Mail Login was made to work out-of-the-box, but you may override the configuration by simply publishing the config file if you're not using Laravel's defaults.

```
php artisan vendor:publish --provider="Laragear\EmailLogin\EmailLoginServiceProvider" --tag="config"
```

After that, you will receive the `config/email-login.php` config file with an array like this:

```
return [
    'guard' => null,
    'route' => [
        'name' => 'login.mail',
        'view' => 'laragear::email-login.web.login',
    ],
    'throttle' => [
        'store' => null,
        'prefix' => 'throttle'
    ],
    'expiration' => 5,
    'cache' => [
        'store' => null,
        'prefix' => 'email-login'
    ],
    'mail' => [
        'mailer' => null,
        'connection' => null,
        'queue' => null,
        'view' => 'laragear::email-login.mail.login',
    ],
];
```

### Guard

[](#guard)

```
return [
    'guard' => null,
];
```

The default Authentication Guard to use. When `null`, it fall backs to the application default, which is usually `web`. The User Provider set for the guard is used to find the user.

### Route name &amp; View

[](#route-name--view)

```
return [
    'route' => [
        'name' => 'login.mail',
        'view' => 'laragear::email-login.web.login',
    ],
];
```

This named route is linked in the email, which contains the view form to log in the user.

### Throttle

[](#throttle)

```
return [
    'throttle' => [
        'store' => null,
        'prefix' => 'throttle'
    ],
];
```

When [throttling the email](#opaque-throttling), this configuration will be used to set which cache store and prefix to use.

### Cache

[](#cache)

```
return [
    'cache' => [
        'store' => null,
        'prefix' => 'email-login'
    ],
];
```

Email Login intents are saved into the cache for a given duration. Here you can change the cache store and prefix used to store them. When `null`, it will use the default application store.

### Link expiration

[](#link-expiration)

```
return [
    'expiration' => 5,
];
```

When mailing the link, a signed URL will be generated with an expiration time. You can control how many minutes to keep the link valid until it is expunged by the cache store.

### Mail driver

[](#mail-driver)

```
return [
    'mail' => [
        'mailer' => null,
        'connection' => null,
        'queue' => null,
        'markdown' => 'laragear::email-login.mail.login',
    ],
];
```

This specifies which mail driver to use to send the login email, and the queue connection and name that will receive it. When `null`, it will fall back to the application default, which is usually `smtp`.

This also sets the default view to use to create the email, which [uses Markdown](https://laravel.com/docs/11.x/mail#markdown-mailables).

Filament Login by Email
-----------------------

[](#filament-login-by-email)

If you want for users to log in through their Email, you can use the `Laragear\EmailLogin\Filament\EmailLogin` page. It extends the default Filament Login page for the panel, but instead of using the usual user-password combination, it validates the email, sends the mail and receives the login attempt.

```
use Filament\Panel;
use Laragear\EmailLogin\Filament\EmailLogin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->login(EmailLogin::class);
}
```

If the class does not adjust to your panel, you may create a class extending this Email Login, and override any of the included methods. From these methods, the most useful to override are:

- `useTokenStore()`: Sets the token store to use.
- `getEmailFormComponent()`: Returns the Input that will hold the Email.
- `notifyEmailSent()`: Notifies the user the email has been sent.
- `getCredentialsFromFormData()`: Returns the Credentials used to find the user.
- `handleInvalidToken()`: Handles what to do if the token is invalid.
- `notifyInvalidToken()`: Notifies the user that token is invalid.

Important

The Login relies heavily on the `email` input. If you wish, you may alter the form to find the user by either username or email, or any other type of input.

Laravel Octane Compatibility
----------------------------

[](#laravel-octane-compatibility)

- There are no singletons using a stale application instance.
- There are no singletons using a stale config instance.
- There are no singletons using a stale request instance.
- Two static properties accessible to write are
    - `LoginByMailRequest::$destroyOnRegeneration`
    - `EmailLoginBroker::$tokenGenerator`

There should be no problems using this package with Laravel Octane.

Security
--------

[](#security)

If you discover any security-related issues, please [use the online form](https://github.com/Laragear/EmailLogin/security).

### Blocking authentication after the email is sent.

[](#blocking-authentication-after-the-email-is-sent)

Once the Login Email is sent to the user, the `LoginByEmailRequest` won't be able to block the authentication procedure since it does not check for anything more than a valid Email Login Intent.

For example, if a user is banned *after* the login email is sent, the user will still be able to authenticate.

To avoid this, extend the `LoginByEmailRequest` and modify the `login()` method to add further checks on a manually retrieved user. Then use this new class on your login controller of choice.

```
use App\Models\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Validation\ValidationException;
use Laragear\EmailLogin\Http\Requests\LoginByEmailRequest;

class MyLoginRequest extends LoginByEmailRequest
{
    /**
     * Proceed to log in the user after a successful form submission.
     */
    protected function login(StatefulGuard $guard, mixed $id, bool $remember): void
    {
        $user = User::whereNull('banned_at')->find($id);

        if (!$user) {
            throw ValidationException::withMessages([
                'email' => 'The user for this email has been banned.'
            ]);
        }

        $guard->login($user, $remember);
    }
}
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

Laravel is a Trademark of Taylor Otwell. Copyright © 2011–2026 Laravel LLC.

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance87

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~49 days

Recently: every ~73 days

Total

12

Last Release

64d ago

Major Versions

v1.1.0 → v2.0.02025-03-23

2.x-dev → v3.0.02025-05-20

v3.1.1 → 4.x-dev2026-03-08

PHP version history (3 changes)v1.0.0PHP ^8.1

v2.0.0PHP ^8.2

4.x-devPHP ^8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5141911?v=4)[Italo](/maintainers/DarkGhostHunter)[@DarkGhostHunter](https://github.com/DarkGhostHunter)

---

Top Contributors

[![DarkGhostHunter](https://avatars.githubusercontent.com/u/5141911?v=4)](https://github.com/DarkGhostHunter "DarkGhostHunter (20 commits)")

---

Tags

laravelAuthenticationmailemaillogin

### Embed Badge

![Health badge](/badges/laragear-email-login/health.svg)

```
[![Health](https://phpackages.com/badges/laragear-email-login/health.svg)](https://phpackages.com/packages/laragear-email-login)
```

###  Alternatives

[tymon/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

11.5k49.1M348](/packages/tymon-jwt-auth)[php-open-source-saver/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

8359.8M53](/packages/php-open-source-saver-jwt-auth)[laragear/two-factor

On-premises 2FA Authentication for out-of-the-box.

339785.3k8](/packages/laragear-two-factor)[auth0/login

Auth0 Laravel SDK. Straight-forward and tested methods for implementing authentication, and accessing Auth0's Management API endpoints.

2745.0M3](/packages/auth0-login)[laragear/webauthn

Authenticate users with Passkeys: fingerprints, patterns and biometric data.

403480.4k8](/packages/laragear-webauthn)[alajusticia/laravel-logins

Session management in Laravel apps, user notifications on new access, support for multiple separate remember tokens, IP geolocation, User-Agent parser

2011.0k](/packages/alajusticia-laravel-logins)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
