https://github.com/cesargb/laravel-magiclink
Create link for authenticate in Laravel without password or get private content
https://github.com/cesargb/laravel-magiclink
auth authentication auto laravel link login passwordless
Last synced: 9 days ago
JSON representation
Create link for authenticate in Laravel without password or get private content
- Host: GitHub
- URL: https://github.com/cesargb/laravel-magiclink
- Owner: cesargb
- License: mit
- Created: 2017-07-25T18:31:29.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2025-09-05T04:46:55.000Z (4 months ago)
- Last Synced: 2025-09-23T23:11:34.102Z (4 months ago)
- Topics: auth, authentication, auto, laravel, link, login, passwordless
- Language: PHP
- Homepage:
- Size: 265 KB
- Stars: 434
- Watchers: 7
- Forks: 49
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
README
# MagicLink for Laravels App
Through the `MagicLink` class we can create a secure link that later
being visited will perform certain actions, which will allow us
offer secure content and even log in to the application.
[](https://packagist.org/packages/cesargb/laravel-magiclink)

[](https://github.com/cesargb/laravel-magiclink/actions/workflows/style-fix.yml)
[](https://scrutinizer-ci.com/g/cesargb/laravel-magiclink)
[](https://packagist.org/packages/cesargb/laravel-magiclink)
## Contents
- [Installation](#installation)
- [Use case](#use-case)
- [Create a MagicLink](#create-a-magiclink)
- [Actions](#actions)
- [Login](#login-action)
- [Download file](#download-file-action)
- [View](#view-action)
- [Http Response](#http-response-action)
- [Controller](#controller-action)
- [Custom Action](#custom-action)
- [Protect with an access code](#protect-with-an-access-code)
- [Lifetime](#lifetime)
- [Events](#events)
- [Customization](#customization)
- [Rate limiting](#rate-limiting)
- [Testing](#testing)
- [Contributing](#contributing)
- [Security](#security)
## Installation
You can install this package via composer using:
```bash
composer require cesargb/laravel-magiclink
```
### Preparing the database
You need to publish the migration to create the `magic_links` table:
```bash
php artisan vendor:publish --provider="MagicLink\MagicLinkServiceProvider" --tag="migrations"
```
After that, you need to run migrations.
```bash
php artisan migrate
```
## Use case
With this example you can create a link to auto login on your application with
the desired user:
```php
use MagicLink\Actions\LoginAction;
use MagicLink\MagicLink;
$urlToAutoLogin = MagicLink::create(new LoginAction($user))->url
```
## Create a MagicLink
The `MagicLink` class has the `create` method to generate a class that through
the `url` property we will obtain the link that we will send to our visitor.
This method requires the action to be performed.
## Actions
Each MagicLink is associated with an action, which is what will be performed
once the link is visited.
- [Login Action](#login-action)
- [Download file Action](#download-file-action)
- [View Action](#view-action)
- [Http Response Action](#http-response-action)
- [Http Response](#http-response-action)
- [Controller](#controller-action)
- [Custom Action](#custom-action)
- [Custom Base URL](#custom-base-url)
### Login Action
Through the `LoginAction` action, you can log in to the application using the
generated link by `MagicLink`.
Your constructor supports the user who will login. Optionally we can specify
the [HTTP response](https://laravel.com/docs/master/responses) using the method
`response` or specify other guard with method `guard`.
Examples:
```php
use MagicLink\Actions\LoginAction;
use MagicLink\MagicLink;
// Sample 1; Login and redirect to dash board
$action = new LoginAction(User::first());
$action->response(redirect('/dashboard'));
$urlToDashBoard = MagicLink::create($action)->url;
// Sample 2; Login and view forms to password reset and use guard web
$action = new LoginAction(User::first());
$action->response(view('password.reset', ['email' => 'user@example.tld']));
$urlShowView = MagicLink::create($action)->url;
// Sample 3; Login in other guard and redirect default
$action = new LoginAction(User::first());
$action->guard('customguard');
$urlShowView = MagicLink::create($action)->url;
// Sample 4; Login and remember me
$action = new LoginAction(User::first());
$action->remember();
$urlShowView = MagicLink::create($action)->url;
```
### Download file Action
This action, `DownloadFileAction`, permit create a link to download a private file.
The constructor require the file path.
Example:
```php
use MagicLink\Actions\DownloadFileAction;
use MagicLink\MagicLink;
// Url to download the file storage_app('private_document.pdf')
$url = MagicLink::create(new DownloadFileAction('private_document.pdf'))->url;
// Download file with other file_name
$action = new DownloadFileAction('private_document.pdf', 'your_document.pdf');
$url = MagicLink::create($action)->url;
// Download file from other disk
$action = new DownloadFileAction('private_document.pdf')->disk('ftp');
$url = MagicLink::create($action)->url;
```
### View Action
With the action `ViewAction`, you can provide access to the view. You can use
in his constructor the same arguments than method `view` of Laravel.
Example:
```php
use MagicLink\Actions\ViewAction;
use MagicLink\MagicLink;
// Url to view a internal.blade.php
$url = MagicLink::create(new ViewAction('internal', [
'data' => 'Your private custom content',
]))->url;
```
### Http Response Action
Through the `ResponseAction` action we can access private content without need
login. Its constructor accepts as argument the
[HTTP response](https://laravel.com/docs/responses)
which will be the response of the request.
Examples:
```php
use MagicLink\Actions\ResponseAction;
use MagicLink\MagicLink;
$action = new ResponseAction(function () {
Auth::login(User::first());
return redirect('/change_password');
});
$urlToCustomFunction = MagicLink::create($action)->url;
```
### Controller Action
`MagicLink` can directly call a controller via the `ControllerAction` action.
The constructor requires one argument, the name of the controller class. With
the second argument can call any controller method, by default it will use the
`__invoke` method.
```php
use MagicLink\Actions\ControllerAction;
use MagicLink\MagicLink;
// Call the method __invoke of the controller
$url = MagicLink::create(new ControllerAction(MyController::class))->url;
// Call the method show of the controller
$url = MagicLink::create(new ControllerAction(MyController::class, 'show'))->url;
```
### Custom Action
You can create your own action class, for them you just need to extend with
`MagicLink\Actions\ActionAbstract`
```php
use MagicLink\Actions\ActionAbstract;
class MyCustomAction extends ActionAbstract
{
public function __construct(public int $variable)
{
}
public function run()
{
// Do something
return response()->json([
'success' => true,
'data' => $this->variable,
]);
}
}
```
You can now generate a Magiclink with the custom action
```php
use MagicLink\MagicLink;
$action = new MyCustomAction('Hello world');
$urlToCustomAction = MagicLink::create($action)->url;
```
### Custom Base URL
To set the base URL for a magic link, you can use the `baseUrl` method. This method ensures that the provided base URL has a trailing slash, making it ready for URL generation.
```php
$magiclink = MagicLink::create($action);
$magiclink->baseUrl("http://example.com");
$urlShowView = $magiclink->url; // http://example.com/magiclink/...
```
## Protect with an access code
Optionally you can protect the resources with an access code.
You can set the access code with method `protectWithAccessCode`
which accepts an argument with the access code.
```php
$magiclink = MagicLink::create(new DownloadFileAction('private_document.pdf'));
$magiclink->protectWithAccessCode('secret');
$urlToSend = $magiclink->url;
```
### Custom view for access code
You can customize the view of the access code form with the config file `magiclink.php`:
```php
'access_code' => [
'view' => 'magiclink::access-code', // Change with your view
],
```
This is the [default view](/resources/views/ask-for-access-code-form.blade.php)
## Lifetime
By default a link will be available for 72 hours after your creation. We can
modify the life time in minutes of the link by the `$lifetime` option
available in the `create` method. This argument accepts the value `null` so
that it does not expire in time.
```php
$lifetime = 60; // 60 minutes
$magiclink = MagicLink::create(new ResponseAction(), $lifetime);
$urlToSend = $magiclink->url;
```
We also have another option `$numMaxVisits`, with which we can define the
number of times the link can be visited, `null` by default indicates that there
are no visit limits.
```php
$lifetime = null; // not expired in the time
$numMaxVisits = 1; // Only can visit one time
$magiclink = MagicLink::create(new ResponseAction(), $lifetime, $numMaxVisits);
$urlToSend = $magiclink->url;
```
## Events
MagicLink can fires three events:
### MagicLinkWasCreated
Event `MagicLink\Events\MagicLinkWasCreated`
This event is fired when a magic link is created.
### MagicLinkWasVisited
Event `MagicLink\Events\MagicLinkWasVisited`
This event is fired when a magic link is visited.
### MagicLinkWasDeleted
Event `MagicLink\Events\MagicLinkWasDeleted`
This event is fired when you disable mass deletion. Add this line in your
`.env` file to disable mass deletion:
```.env
# Disable mass deletion for enable event MagicLinkWasDeleted
MAGICLINK_DELETE_MASSIVE=false
```
> [!WARNING]
> If you disable mass deletion, the cleanup will be performed one by one.
> If you have many records, this can be an issue.
## Customization
### Config
To custom this package you can publish the config file:
```bash
php artisan vendor:publish --provider="MagicLink\MagicLinkServiceProvider" --tag="config"
```
And edit the file `config/magiclink.php`
### Migrations
To customize the migration files of this package you need to publish the migration files:
```bash
php artisan vendor:publish --provider="MagicLink\MagicLinkServiceProvider" --tag="migrations"
```
You'll find the published files in `database/migrations/*`
### Custom response when magiclink is invalid
When the magicLink is invalid by default the http request return a status 403.
You can custom this response with config `magiclink.invalid_response`.
#### Response
To return a response, use class `MagicLink\Responses\Response::class`
same `response()`, you can send the arguments with options
Example:
```php
'invalid_response' => [
'class' => MagicLink\Responses\Response::class,
'options' => [
'content' => 'forbidden',
'status' => 403,
],
],
```
#### Abort
To return a exception and let the framework handle the response,
use class `MagicLink\Responses\AbortResponse::class`.
Same `abort()`, you can send the arguments with options.
Example:
```php
'invalid_response' => [
'class' => MagicLink\Responses\AbortResponse::class,
'options' => [
'message' => 'You Shall Not Pass!',
'status' => 403,
],
],
```
#### Redirect
Define class `MagicLink\Responses\RedirectResponse::class` to
return a `redirect()`
```php
'invalid_response' => [
'class' => MagicLink\Responses\RedirectResponse::class,
'options' => [
'to' => '/not_valid_path',
'status' => 301,
],
],
```
#### View
Define class `MagicLink\Responses\ViewResponse::class` to
return a `view()`
```php
'invalid_response' => [
'class' => MagicLink\Responses\ViewResponse::class,
'options' => [
'view' => 'invalid',
'data' => [],
],
],
```
## Rate limiting
You can limit the number of requests per minute for a magic link. To do this, you need to
set the `MAGICLINK_RATE_LIMIT` environment variable to the desired value.
By default, the rate limit is disable with value 'none', but you can set a value
to limit the requests. For example, to limit the requests to 100 per minute, set
```bash
# .env
MAGICLINK_RATE_LIMIT=100
```
## Testing
Run the tests with:
``` bash
composer test
```
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
## Security
If you discover any security-related issues, please email cesargb@gmail.com
instead of using the issue tracker.
## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.