Giter Site home page Giter Site logo

laravel-passwordless-login's Introduction

Laravel Passwordless Login

A simple, safe magic login link generator for Laravel

build status

This package provides a temporary signed route that logs in a user. What it does not provide is a way of actually sending the link to the route to the user. This is because I don't want to make any assumptions about how you communicate with your users.

Installation

composer require grosv/laravel-passwordless-login

Simple Usage

use App\User;
use Grosv\LaravelPasswordlessLogin\LoginUrl;

function sendLoginLink()
{
    $user = User::find(1);

    $generator = new LoginUrl($user);
    $generator->setRedirectUrl('/somewhere/else'); // Override the default url to redirect to after login
    $url = $generator->generate();

    //OR Use a Facade
    $url = PasswordlessLogin::forUser($user)->generate();

    // Send $url in an email or text message to your user
}

Using A Trait

Because some sites have more than one user-type model (users, admins, etc.), you can use a trait to set up the default configurations for each user type. The methods below are provided by the trait, so you only need to include the ones for which you want to use a different value.

use Grosv\LaravelPasswordlessLogin\Traits\PasswordlessLogin;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use PasswordlessLogin;

    public function getGuardNameAttribute(): string 
    {
        return config('laravel-passwordless-login.user_guard');
    }
    
    public function getShouldRememberLoginAttribute(): bool
    {
        return config('laravel-passwordless-login.remember_login');
    }

    public function getLoginRouteExpiresInAttribute(): int
    {
        return config('laravel-passwordless-login.login_route_expires');
    }

    public function getRedirectUrlAttribute(): string
    {
        return config('laravel-passwordless-login.redirect_on_success');
    }
}

If you are using the PasswordlessLogin Trait, you can generate a link using the defaults defined in the trait by simply calling createPasswordlessLoginLink() on the user you want to log in.

The biggest mistake I could see someone making with this package is creating a login link for one user and sending it to another. Please be careful and test your code. I don't want anyone getting mad at me for someone else's silliness.

Configuration

You can publish the config file or just set the values you want to use in your .env file:

LPL_USER_MODEL=App\User
LPL_REMEMBER_LOGIN=false
LPL_LOGIN_ROUTE=/magic-login
LPL_LOGIN_ROUTE_NAME=magic-login
LPL_LOGIN_ROUTE_EXPIRES=30
LPL_REDIRECT_ON_LOGIN=/
LPL_USER_GUARD=web
LPL_USE_ONCE=false
LPL_INVALID_SIGNATURE_MESSAGE="Expired or Invalid Link"

LPL_USER_MODEL is the the authenticatable model you are logging in (usually App\User)

LPL_REMEMBER_LOGIN is whether you want to remember the login (like the user checking Remember Me)

LPL_LOGIN_ROUTE is the route that points to the login function this package provides. Make sure you don't collide with one of your other routes.

LPL_LOGIN_ROUTE_NAME is the name of the LPL_LOGIN_ROUTE. Again, make sure it doesn't collide with any of your existing route names.

LPL_LOGIN_ROUTE_EXPIRES is the number of minutes you want the link to be good for. I recommend you set the shortest value that makes sense for your use case.

LPL_REDIRECT_ON_LOGIN is where you want to send the user after they've logged in by clicking their magic link.

LPL_USE_ONCE is whether you want a link to expire after first use (uses cache to store used links)

LPL_INVALID_SIGNATURE_MESSAGE is a custom message sent when we abort with a 401 status on an invalid or expired link. You can also add some custom logic on how to deal with invalid or expired links by handling InvalidSignatureException and ExpiredSignatureException in your Handler.php file.

Reporting Issues

For security issues, please email me directly at [email protected]. For any other problems, use the issue tracker here.

Contributing

I welcome the community's help with improving and maintaining all my packages. Just be nice to each other. Remember we're all just trying to do our best.

laravel-passwordless-login's People

Contributors

afzafri avatar ashleighsims avatar benrolfe avatar edalzell avatar edgrosvenor avatar felixdorn avatar iman-ragab avatar innoflash avatar jhumanj avatar joe-pritchard avatar kamiben avatar laravel-shift avatar likeadeckofcards avatar pktharindu avatar reinisl avatar rico avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-passwordless-login's Issues

Microsoft 'Safelinks' (Defender) breaks links.

When a client uses a service like Microsoft's 'SafeLinks', one-use login links are broken. It seems that they effectively get used up by a GET to HEAD request that the link checking service does. Here's some more info on another product having the same issue: FusionAuth/fusionauth-issues#629 (and loads of other repos referencing that issue too).

Anyone found a way around this with this package? Presumably it would have the same impact on Laravel's bundled email verification.

Magic link never expire despite a set expiration

I may have discovered an issue with the package :

How to reproduce : generate a link and wait for it to expire. The link will still work.

Analysis
When the magic link is generated, it is generated against the following route

 Route::get(
    //config('laravel-passwordless-login.login_route').'/{expires}/{uid}',
    config('laravel-passwordless-login.login_route').'/{uid}',
    [LaravelPasswordlessLoginController::class, 'login']
)->middleware('web')->name(config('laravel-passwordless-login.login_route_name'));

As such, the expires parameter is coded in the path, and not as a parameter. (&expires=timestamp)

However, Laravel's function signatureHasNotExpired (in laravel/framework/src/Illuminate/Routing/UrlGenerator.php) expects the expires data as a parameter. If it is not present the link is simply considered a non expiring signed link.

  public function signatureHasNotExpired(Request $request)
     {
    $expires = $request->query('expires');
    return ! ($expires && Carbon::now()->getTimestamp() > $expires);
      }

So the function returns true and simply tests the signature which is correct. The user is now authenticated.

I have implemented the following fix : not using the expires as a paremeter : this way expires is set as a parameter again and not include it in the route:

 Route::get(
    //config('laravel-passwordless-login.login_route').'/{uid}',
    config('laravel-passwordless-login.login_route').'/{uid}',
    [LaravelPasswordlessLoginController::class, 'login']
)->middleware('web')->name(config('laravel-passwordless-login.login_route_name'));

That way : the url is still signed (against all parameters, including expiration, so still secure), the signatureHasNotExpired works and the link expires as inteded.

I'll submit a PR to discuss the change.

How to use new

I'm having difficulty using the newish LPL_MIDDLEWARE env var.

I need to inject some middleware called firetest before every request this package deals with. I can add it via the config like this and it works fine:

<?php

use Grosv\LaravelPasswordlessLogin\HandleAuthenticatedUsers;

return [
    'user_model' => env('LPL_USER_MODEL', 'App\User'),
    // etc etc 
    'middleware' => env('LPL_MIDDLEWARE', ['firetest', 'web', HandleAuthenticatedUsers::class]),
];

How would I add it in .env?

I've tried:

LPL_MIDDLEWARE="['firetest', 'web', HandleAuthenticatedUsers::class]" #result: Target class [['firetest', 'web', HandleAuthenticatedUsers] does not exist
LPL_MIDDLEWARE="['firetest', 'web', Grosv\LaravelPasswordlessLogin\HandleAuthenticatedUsers\HandleAuthenticatedUsers::class]" #result: White screen no visible errors.
LPL_MIDDLEWARE="['firetest', 'web', Grosv\LaravelPasswordlessLogin\HandleAuthenticatedUsers\HandleAuthenticatedUsers]" #result: White screen no visible errors.
LPL_MIDDLEWARE="['firetest', 'web']" #result: Target class [['firetest', 'web']] does not exist.
LPL_MIDDLEWARE="\['firetest', 'web'\]" #result: Target class [['firetest', 'web']] does not exist.

I'm thinking there's no way to define an array in .env without having it exploded or something to turn it into an array when it's retrieved, so is the LPL_MIDDLEWARE actually usable? I suppose if one only want's to define a single middleware it is. Any thoughts please?

Event Listening - Login Success/Failure

Hi there,

Just wondering if there is an existing mechanism to listen for authentication events, in particular when a user successfully uses a login link or when a login link is accessed but has expired.

The purpose is mainly for user access logging and/or rate limiting etc.

If such functionality does not yet exist (nor contemplated), is there any appetite for me to prepare a PR?

Does not work with StudlyCase namespaces

Hello, thanks for a great package!

I'm trying to use this package where the User model namespace is StudlyCaseHelloWorld\Models\User.

The url that is generated looks like:

/magic-login/26
    ?expires=1591106096
    &user_type=helloworld-models-user
    &signature=3e62a0eb8d189584d11850...

The trouble is getUserClass returns Helloworld\Models\User with a lower case 'w' which means $userModel::findOrFail(request('uid')) fails as the namespace isn't correct.

The README mentions setting LPL_USER_MODEL but I don't believe that is being used anywhere apart from in the tests?

Docs update

So i dont know what you guys think but i was suggesting that we promote more the use of the config file or the trait.

I have seen that so far we are requiring like 9 more entries on the this package on the .env file and if we think of something new it means thats one more line.

The whole database uses only 5-6 lines on the .env and a whole load of config data.

I dont know but what do you think?

Argument 1 passed to Grosv\LaravelPasswordlessLogin\LoginUrl::__construct() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\Models\Employee given, called in C:\xampp\htdocs\arabic company\app\Http\Controllers\auth\Login.php on line 16

i am trying to use the simple exemple but i get this error : Argument 1 passed to Grosv\LaravelPasswordlessLogin\LoginUrl::__construct() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\Models\Employee given, called in C:\xampp\htdocs\arabic company\app\Http\Controllers\auth\Login.php on line 16

this is my code:

use Grosv\LaravelPasswordlessLogin\LoginUrl;
    public function store(Request $request){
        $user = Employee::where('email', $request->email)->first();
        $generator = new LoginUrl($user);   //<- this line 16
        $generator->setRedirectUrl('/'); // Override the default url to redirect to after login
        $url = $generator->generate();
        dd($url);
    }

am i doing something wrong?

A basic API implementation

Hi, great library! I use laravel as a restful api with a react frontend, so for me I didn't need a lot of what your library offers. So I made a very basic watered down version that will hopefully be of use to others.

MagicLinkController.php

class MagicLinkController extends Controller
{
    public function generate(Request $request)
    {
        $user = User::find(101);

        $magicLink = new MagicLinkService($user);

        $magicLink->setRedirectUrl('/somewhere/else');
        
        $url = $magicLink->generate();

        return response()->json(['url' => $url], 200);
    }

    public function check(Request $request, UrlGenerator $urlGenerator)
    {
        if (!$request->hasValidSignature() || !$urlGenerator->hasCorrectSignature($request) || !$urlGenerator->signatureHasNotExpired($request)) {
            throw new AuthorizationException;
        }

        $user = User::findOrFail($request->id);

        return response()->json([
            'token' => $user->createToken('web')->plainTextToken,
            'user' => $user,
            'redirect_to' => $request->redirect_to
        ], 200);
    }
}

MagicLinkService.php

class MagicLinkService
{
    public $user;
    protected $routeName = 'magic-link';
    protected $routeExpires = 30;
    protected $redirectUrl = null;

    public function __construct(User $user) {
        $this->user = $user;
    }

    public function generate()
    {
        return URL::temporarySignedRoute(
            $this->routeName,
            now()->addMinutes($this->routeExpires),
            [
                'id' => $this->user->getAuthIdentifier(),
                'redirect_to' => $this->redirectUrl
            ]
        );
    }

    public function setRedirectUrl(string $redirectUrl)
    {
        $this->redirectUrl = $redirectUrl;
    }
}

routes/api.php

Route::post('magic-link', 'MagicLinkController@generate');
Route::get('magic-link/{id}', 'MagicLinkController@check')->name('magic-link');

Login route expires after first use

Hi, i was thinking that maybe should be a variable that determine if the login route should expire after the first use, something like this:

LPL_LOGIN_ROUTE_EXPIRES_AFTER_FIRST_USE=true

Then you will have two expirations settings, whatever happends first (the minutes have passed or after first use)

Thanks.

401 Unauthorized

I did a setup as mentioned in the readme, it works fine on local, but when i deploy on production, it gives a 401 Unauthorised error on

/magic-url/1?expires=1661899121&redirect_to=portal&user_type=app-models-user&signature=xxx

Error when user is already authenticated but RouteServiceProvider::HOME is not defined

An error is thrown by HandleAuthenticatedUsers.php if RouteServiceProvider::HOME is not defined. In my application I use the alternative home() method instead.

I've fixed it and opened a PR if it helps :) - #83

My PR checks for the existence of the home() method, and falls back to the constant if it's not defined, and if the constant is not defined either only then does it fall back to using the config value. It also handles the case where the programmer has changed their app namespace.

Everything else should work the same as it does now.

"Security" issue

Hi:

I've always coded my scripts trying to hide "id's", and here you created the link with getAuthIdentifier(), so user will know its "id" in the system.

Is there anyway to hide this in your class?

Maybe you can use "username" or "email" better... it's something user already knows and "harmless"

Thank you

Laravel-Vapor Production Issue

I have a laravel app that uses MAgic-Link Passwordless login. On local environment I can click the link and login successfully with the following url:
href="http://localhost:8000/magic-login/493eb4f7-18ce-4481-a26e-a3fa8c887220?expires=1651125222&amp;user_type=app-models-user&amp;signature=a4ceb0c897aeee5f061e9da436857bbcb42568bc69a94450521cc63e2ccbbc3d"

But it doesn't work on Production and this is the link that is created:
href="https://precious-rain-wbicx1zdorzr.vapor-farm-b1.com/magic-login/493eb4f7-18ce-4481-a26e-a3fa8c887220?expires=1651220763&amp;user_type=app-models-user&amp;signature=2d440e40a9d50f6d246c4f12fbb84979caf28b211f9995b06ed6b5667aa3edf2"

There is a definite difference of the 2 links

Can anyone please help ?

Thank you in advance

API implementation

So from the current setting i see this works only for a web interface but how about we extend it to API logins as well.

For an API a user might wanna generate a token or do something on success. I am thinking of making a callback in the trait to do extra staff. That might as well fix the issue the last issue was having. Will try implement it later today and you guys evaluate

Argument 1 passed to Grosv\LaravelPasswordlessLogin\LoginUrl::__construct() must be an instance of Grosv\LaravelPasswordlessLogin\Models\User, instance of App\User given

It is possible that I am not doing it right since I am new to laravel. But I have been doing almost the same thing for other packages and it has been fine.

As for this package, it kept on reading the Models/User in the LoginUrl class. I will get the error like the title mentioned above.

But when I changed the LoginUrl to use App\User(which is my user model with a different table name), it works. Url generated nicely.

So I am not sure if this is a bug or an issue or it is meant to be this way.

Thanks!

Unable to publish config, small tweak.

Whilst setting this up with Laravel 6, I wasn't able to publish the config.

When I published with this php artisan vendor:publish --tag=passwordless-login-config:
Kept getting the error:

Can't locate path: <0>
Can't locate path: <1>

Had to change from this:

$this->publishes([
   __DIR__.'../config/config.php', config_path('laravel-passwordless-login.php'),
], 'passwordless-login-config');

to

$this->publishes([
    __DIR__.'/../config/config.php' => config_path('laravel-passwordless-login.php'),
], 'passwordless-login-config');

Works fine now. If you want this as a PR lemme know 👍🏼
Love your work.

Dynamic redirect URL

Hi, is possible to implement a dynamic redirect url ?? something like this

$user = User::find(1);
$generator = new LoginUrl($user);
$redirect_url = "/home";
$url = $generator->generate($redirect_url);

Thanks.

Magic Passwordless link handle POST calls

So I have a use case my side. I am adding a payment Gateway and they are posting data to the URL specified.

Do you think we can make the package handle POST calls as well?

There is useful data incoming from the other server.

Composer Error on Laravel 6

Here's the error i found :

Using version ^1.4 for grosv/laravel-passwordless-login
./composer.json has been updated
Running composer update grosv/laravel-passwordless-login
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Root composer.json requires laravel/framework ^7.0, found laravel/framework[v7.0.0, ..., 7.x-dev] but the package is fixed to v6.18.13 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
Problem 2
- Root composer.json requires facade/ignition ^2.0, found facade/ignition[dev-master, 2.0.0, ..., 2.x-dev (alias of dev-master)] but the package is fixed to 1.16.1 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
Problem 3
- Root composer.json requires nunomaduro/collision ^4.1, found nunomaduro/collision[v4.1.0, ..., v4.x-dev] but the package is fixed to v3.0.1 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.`

My Laravel Version is 6.18.13

Redirecting on success - config overriding

Hey, quick question.

In HandleAuthenticatedUsers, there is the following code:

                $home = class_exists(\App\Providers\RouteServiceProvider::class)
                    ? \App\Providers\RouteServiceProvider::HOME
                    : config('laravel-passwordless-login.redirect_on_success', '/');

Is there a reason the config value is not used ahead of the HOME constant? We always want the user redirected to a particular route when logged in via passwordless, a route that isn't the same as the HOME constant value.

Pls, how can I make the link never expire?

Is there a way to make links that never expires?
If I put never on the env var, I'm getting an error that a int is required.

Comments that this is not secure enough is not welcome, just let me know if there is a way to get this to work as I'm using it in a very unique way.

Invalidating links

Hi,

I was wondering if it was possible to invalidate a login link after an action was done by a user (eg, set a password).
My current use case is that a user has to be approved before allowing them to login, and once the login link has been sent they need to set a password. Users will undoubtedly forget to set one so the link can be used multiple times. However, I would like to be able to invalidate a login link after a password has been set. Is this already possible but undocumented or would this be a new feature?

Edit: Something that could potentially be beneficial as well, is to be able to pass along a redirect URL on failing to login (expired link or the likes)

Composer Error

Problem 1
    - Installation request for grosv/laravel-passwordless-login ^1.2 -> satisfiable by grosv/laravel-passwordless-login[1.2.0].
    - Conclusion: remove laravel/framework v5.8.38
    - Conclusion: don't install laravel/framework v5.8.38
    - grosv/laravel-passwordless-login 1.2.0 requires illuminate/support ^6.0|^7.0 -> satisfiable by laravel/framework[6.x-dev, 7.x-dev], illuminate/support[6.x-dev, 7.x-dev, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4, v6.1.0, v6.10.0, v6.11.0, v6.12.0, v6.13.0, v6.13.1, v6.14.0, v6.15.0, v6.15.1, v6.16.0, v6.17.0, v6.17.1, v6.18.0, v6.18.1, v6.18.10, v6.18.11, v6.18.12, v6.18.13, v6.18.14, v6.18.15, v6.18.16, v6.18.17, v6.18.18, v6.18.19, v6.18.2, v6.18.20, v6.18.21, v6.18.22, v6.18.23, v6.18.24, v6.18.25, v6.18.26, v6.18.27, v6.18.28, v6.18.29, v6.18.3, v6.18.30, v6.18.31, v6.18.32, v6.18.33, v6.18.34, v6.18.35, v6.18.4, v6.18.5, v6.18.6, v6.18.7, v6.18.8, v6.18.9, v6.2.0, v6.3.0, v6.4.1, v6.5.0, v6.5.1, v6.5.2, v6.6.0, v6.6.1, v6.6.2, v6.7.0, v6.8.0, v7.0.0, v7.0.1, v7.0.2, v7.0.3, v7.0.4, v7.0.5, v7.0.6, v7.0.7, v7.0.8, v7.1.0, v7.1.1, v7.1.2, v7.1.3, v7.10.0, v7.10.1, v7.10.2, v7.10.3, v7.11.0, v7.12.0, v7.13.0, v7.14.0, v7.14.1, v7.15.0, v7.16.0, v7.16.1, v7.17.0, v7.17.1, v7.17.2, v7.18.0, v7.19.0, v7.19.1, v7.2.0, v7.2.1, v7.2.2, v7.20.0, v7.21.0, v7.22.0, v7.22.1, v7.22.2, v7.22.3, v7.22.4, v7.23.0, v7.23.1, v7.23.2, v7.24.0, v7.25.0, v7.3.0, v7.4.0, v7.5.0, v7.5.1, v7.5.2, v7.6.0, v7.6.1, v7.6.2, v7.7.0, v7.7.1, v7.8.0, v7.8.1, v7.9.0, v7.9.1, v7.9.2].
    - Can only install one of: laravel/framework[6.x-dev, v5.8.38].
    - Can only install one of: laravel/framework[7.x-dev, v5.8.38].
    - don't install illuminate/support 6.x-dev|don't install laravel/framework v5.8.38
    - don't install illuminate/support 7.x-dev|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.0.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.0.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.0.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.0.3|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.0.4|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.1.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.10.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.11.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.12.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.13.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.13.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.14.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.15.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.15.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.16.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.17.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.17.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.10|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.11|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.12|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.13|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.14|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.15|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.16|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.17|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.18|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.19|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.20|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.21|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.22|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.23|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.24|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.25|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.26|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.27|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.28|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.29|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.3|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.30|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.31|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.32|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.33|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.34|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.35|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.4|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.5|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.6|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.7|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.8|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.18.9|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.2.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.3.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.4.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.5.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.5.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.5.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.6.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.6.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.6.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.7.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v6.8.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.3|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.4|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.5|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.6|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.7|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.0.8|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.1.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.1.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.1.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.1.3|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.10.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.10.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.10.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.10.3|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.11.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.12.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.13.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.14.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.14.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.15.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.16.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.16.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.17.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.17.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.17.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.18.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.19.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.19.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.2.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.2.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.2.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.20.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.21.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.22.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.22.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.22.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.22.3|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.22.4|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.23.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.23.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.23.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.24.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.25.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.3.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.4.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.5.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.5.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.5.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.6.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.6.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.6.2|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.7.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.7.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.8.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.8.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.9.0|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.9.1|don't install laravel/framework v5.8.38
    - don't install illuminate/support v7.9.2|don't install laravel/framework v5.8.38
    - Installation request for laravel/framework (locked at v5.8.38, required as 5.8.*) -> satisfiable by laravel/framework[v5.8.38]

Redirect Issue with new Guest Middleware

Hi there,

Big Fan of your package, thanks for your nice work in advance!!

Unfortunately the newly added guest middleware causes a new problem. I have an app that highly relies on the redirect feature of the passwordless login package. Due to the new guest middleware the redirect will not be executed when a user is already logged in because the login method of LaravelPasswordlessLoginController will never be called and as far as i understand it correct after a dive into your package the redirect logic is executed within the login method of this Controller.

The redirect only happens when being logged out and clicking on the generated link.

Redirects to login if link clicked in an email

This might not be a problem with this but with Chrome but I can't find a workaround,

When I echo out the $url manually and copy and paste it into the address bar, it works flawlessly and redirects to the /admin page which is behind the "Auth" middleware.

http://127.0.0.1:8000/login/1?expires=1602813103&user_type=app-models-user&signature=d331e2e0621709de1abf28b2f593faf066ce0a4c33626d25f9214b672bcad895

But if I email the same exact link to myself, in an <a href="{$url}"></a> tag and click it, it just redirects back to the /login page and the state is unauthenticated.

$generator = new LoginUrl($user);
$generator->setRedirectUrl('/admin');
$url = $generator->generate();

Mail::html("<a href='{$url}'>{$url}</a>", function($message) use ($request) {
   $message->subject('Secure sign in link')
           ->to($request->email);
});

die($url);

Does not Work on production

Hi,
thanks for your package.

It works very well on my localhost...

this is my function on Controller

function sendLoginLink()
    {
        $user = User::find(2);

        $generator = new LoginUrl($user);
        $generator->setRedirectUrl('/home'); // Override the default url to redirect to after login

        return $generator->generate();
    }

which returns this link

http://127.0.0.1:8000/magic-login/2?expires=1615255572&redirect_to=%2Fhome&user_type=app-user&signature=a6255a266fd1568108f5309876aeb8fc416204b1088bb379c050558bde834f81

On live production I got this error:

Symfony\Component\Routing\Exception\RouteNotFoundException Route [] not defined.

I made a few attempts and realized that the error is generated by $generator->generate();
I don't understand why..

Redirect Url doesn't work

Hi!
Thanks for a great package!

I cant get the custom redirect url to work.
This is the code im using:

$generator = new LoginUrl($user);
$generator->setRedirectUrl('/app/' . $deviceName); //device name is a string
$url = $generator->generate();

The link i get is similar to this:
https://domain.name/magic-login/1?expires=1598101993&redirect_to=%2Fapp%2Fdevicenamehere&user_type=app-user&signature=signature

But it always redirects to the root. ie. /
If I change the default redirect to /example.
It always redirects to /example.. but never to the custom redirect url.

Any idea what the problem could be?

Thank you!

REMEBER_LOGIN issue following upgrade to 1.7.0

Hi there,

Firstly, thank you for developing such a great package!

Following the upgrade to 1.7.0, the behaviour of REMEMBER_LOGIN seems to have changed.

We use this package as a form of basic SSO, a URL is generated with a short TTL with USE_ONCE set to true and REMEMBER_LOGIN set to false. Previously this would allow us to login as any User, regardless if we had an existing session or not.

Now, we have to logout of the app before being able to use another passwordless login URL as we're simply redirected back to home, as if REMEMBER_LOGIN is set to true.

I thought this may have been the same issue as #76 but updating 1.7.1 has now introduced an exception when trying to login using a URL when already logged in:

Undefined constant App\Providers\RouteServiceProvider::HOME {"userId":99,"exception":"[object] (Error(code: 0): Undefined constant App\\Providers\\RouteServiceProvider::HOME at /home/user/app/vendor/grosv/laravel-passwordless-login/src/HandleAuthenticatedUsers.php:17)

Logging out of the app allows us to login again using a new URL but otherwise the above exception is thrown.

We're using Laravel 7 at the moment.

Apologies if this report is lacking information, let me know if there's anything further you need.

Thank you again!

Make number of uses configurable (in addition to LPL_USE_ONCE)

I've had a few issues with certain email security systems (like outlook https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/atp-safe-links?view=o365-worldwide ) doing verification on login links we send. This means they visit the link before the user, which records it as used and the user themselves can't then login.

Not sure what the best solution to this would be - my alternative is to turn off LPL_USE_ONCE but I rather not. Perhaps tracking how many times the link was used and setting a maximum number of usages would be a good alternative?

Like setting LPL_NUM_USAGES, which I can then set to 2, or 3 in order to tackle this issue.

Undefined index: password using laravel-admin package

  1. C:\wamp64\www\laravelnew\vendor\laravel\framework\src\Illuminate\Auth\EloquentUserProvider.php:32
  2. {
    
  3.     foreach ($credentials as $key => $value) {
    
  4.         return $key;
    
  5.     }
    
  6. }
    
  7. /**
    
  8.  * Validate a user against the given credentials.
    
  9.  *
    
  10.  * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
    
  11.  * @param  array  $credentials
    
  12.  * @return bool
    
  13.  */
    
  14. public function validateCredentials(UserContract $user, array $credentials)
    
  15. {
    
  16.     $plain = $credentials['password'];
    
  17.     return $this->hasher->check($plain, $user->getAuthPassword());
    
  18. }
    

Custom Redirect URL not working if Guard Name attribute trait is set

Hi,
First of all, thank you for this great package, it has been really great.

My requirement is to have user auto redirected to a dynamic route, depending on what "post" they are going to see.
However, I am not able to have the custom redirect URL to be working using the following code:

$id = 'postid';
$generator = new LoginUrl($user);
$generator->setRedirectUrl('/post/'.$id); 
$url = $generator->generate();

Currently I have 2 type of users, let say its "User" and "Admin". So I need to set the Guard for each users right.
Therefore I used the Traits of this package, because with the traits I can set the Guard Name.

So I did some digging into the package codes, and I noticed that on Line 54 of LaravelPasswordlessLoginController.php :

        return $user->guard_name ? $user->onPasswordlessLoginSuccess($request) : redirect($redirectUrl);

This line here check if the Guard Name attribute for the User model is set or not. If it does set, then it will proceed to call the onPasswordlessLoginSuccess() method, in which it's actually redirect the user to the route defined in getRedirectUrlAttribute() of the Model.

So if I used the included Traits, the custom redirect url method, setRedirectUrl() will not be used at all since it will keep fall back to use the redirect_url attribute in the Model.

Is this supposed to be designed this way, and I am doing something incorrect in my implementation?

Currently, to overcome this problem, I also need to override the onPasswordlessLoginSuccess($request) method in both my user Models like the following:

public function onPasswordlessLoginSuccess($request)
{
    # check if custom url set, redirect to the url
    return ($request->has('redirect_to')) ? redirect($request->redirect_to) : redirect($this->getRedirectUrlAttribute());
}

Again, thank you for this package, really great package. If I am doing something wrong in my implementation, please guide me.
Thanks!

Missing required parameters for [Route: magic-login] [URI: magic-login/{expires}/{uid}].

Hi, i don´t know if i am doing something wrong, but this is my controller:

    function sendLoginLink()
    {
        $user = User::find(8);

        $generator = new LoginUrl($user);
        $generator->setRedirectUrl('/home');
        $url = $generator->generate();

        return $url;
    }

and when i test the url a got this:

Illuminate\Routing\Exceptions\UrlGenerationException
Missing required parameters for [Route: magic-login] [URI: magic-login/{expires}/{uid}].

I am in laravel 7.0.8 with default user model, but with a custom table name and password field.

What could be the problem?

Thanks.

Work on localhost only

Hello! I'm getting the message:

401
UNAUTHORIZED

The env file is correct, the config file is published.. i'm out of ideas.
Thanks

Magic link mail being sent with (undesired) Cc:

Hi there!

I'm using Mailtrap in production to send the magic link login. I noticed (just for these emails) there is a Cc: to myself on all messages.

Checked the .env file and saw no mention of that amongst the LPL_* options. Also reached out to Mailtrap and there isn't any special setting on their side. Any ideas, please?

Thanks!

Integration with Sanctum: Custom error message on invalid signature

I'm in the process of integrating laravel-passwordless-login with my Vuejs SPA.
Using :

  • laravel-passwordless-login1.1.3
  • Sanctum 2.2.0

Sanctum is used here only as an SPA login, so there is no token issued after login. Authentication is only cookie based.

I generate the magic link from an API endpoint, and then prepend the generated link with my SPA url, having a dedicated view that does the magic-login GET with axios, with the url appended.

It does work, the cookies are set, but in the case the signature is invalid (corrupted or time expired), I need to display a message to the user (as the 401 is only in the Ajax call).

I customized the grosv/laravel-passwordless-login/src/LaravelPasswordlessLoginController.php
with :
abort_if(!$request->hasValidSignature(), 401,'The link is not valid');

Do you think it would be a good idea to add an ability to customize this message with config ?
Is it worthy of a pull request ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.