Say goodbye to password troubles and embrace safe and convenient password-free login! This article will guide you how to implement a one-time link-based password-free login system in Laravel applications to improve security and simplify user experience.
This article was reviewed by Younes Rafie and Wern Ancheta. Thanks to all the peer reviewers at SitePoint for getting SitePoint content to its best!
Identity authentication technology continues to evolve, from traditional mailbox-password combinations, to social login, to today's passwordless login (more precisely, "email-only" login). The passwordless login system verifies identity by sending a login link to the user's email.
The login process without password is as follows:
If you forget your application password but remember to register your email, this method is very useful. This technology is also adopted by applications such as Slack. This tutorial will demonstrate how to implement this system in a Laravel application. See the full code here.
First, create a new Laravel application. This tutorial uses Laravel 5.2:
composer create-project laravel/laravel passwordless-laravel 5.2.*
If you already have a Laravel project with user and password, don't worry, we won't modify the normal authentication process, but add a layer on top of it. Users can still choose to log in with their password.
Before running the migration, you need to set up a MySQL database.
Open the .env file in the root directory and enter the host name, user name and database name:
<code>[...] DB_CONNECTION=mysql DB_HOST=localhost DB_DATABASE=passwordless-app DB_USERNAME=username DB_PASSWORD= [...]</code>
If you are using Homestead Improved box, the database/username/password combination is homestead, homestead, secret.
Laravel version 5.2 introduces a great feature: add a prefabricated authentication layer with just one command. Let's do this: <🎜>
composer create-project laravel/laravel passwordless-laravel 5.2.*
This command builds everything you need for authentication, namely views, controllers, and routes.
In the database/migrations directory, you can see that the generated Laravel application contains the migration files that create users tables and password_resets tables.
We will not modify anything because we still want the app to have a normal authentication process.
To create a table, run:
<code>[...] DB_CONNECTION=mysql DB_HOST=localhost DB_DATABASE=passwordless-app DB_USERNAME=username DB_PASSWORD= [...]</code>
The app is now available and users should be able to register and log in using the links in the navigation bar.
Next, we will modify the login link to redirect it to a custom login view where the user will submit only the email address without a password.
Navigate to resources/views/layouts/app.blade.php. There you can find the navigation bar section. Change the line containing the login link (below the conditional statement that checks whether the user has logged out) to:
resources/views/layouts/app.blade.php
php artisan make:auth
When unlogged users try to access protected routes, they should be taken to a new custom login view, rather than the normal login view. This behavior is specified in the authenticate middleware. We need to adjust it:
app/Http/Middleware/Authenticate.php
php artisan migrate
Note that in the else block we have changed the redirect to point to login/magiclink, not the normal login.
The next step is to create a MagicLoginController in the Auth folder:
[...] @if (Auth::guest()) <li><a href="https://www.php.cn/link/9964364bfd2b38643a0b41b981c01f60'/login/magiclink') }}">Login</a></li> <li><a href="https://www.php.cn/link/9964364bfd2b38643a0b41b981c01f60'/register') }}">Register</a></li> [...]
Then there is the route that displays the custom login page:
app/Http/routes.php
class Authenticate { [...] public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->guest()) { if ($request->ajax() || $request->wantsJson()) { return response('Unauthorized.', 401); } else { return redirect()->guest('login/magiclink'); } } return $next($request); } [...]
Let's update the MagicLoginController to include the show action:
app/Http/Controllers/Auth/MagicLoginController.php
php artisan make:controller Auth\MagicLoginController
For the new login view, we will borrow the normal login view, but delete the password field. We also changed the form's post URL to point to /login/magiclink
.
Let's create a magic folder in the views/auth folder to save this new view:
[...] Route::get('/login/magiclink', 'Auth\MagicLoginController@show');
Let's update the newly created view to:
resources/views/auth/magic/login.blade.php
class MagicLoginController extends Controller { [...] public function show() { return view('auth.magic.login'); } [...] }
We will retain the option to log in with password, as users may still choose to log in with password. So if the user clicks on login in the navigation bar, they will see the login view as shown below:
Due to space limitations, the rest of the parts cannot be fully expanded, but the basic ideas are as follows:
str_random()
to generate a random token and store it in the database. UserToken
model to send emails containing login links using Laravel's mail feature. The link should contain the token, email address and remember my value. Use Mail::raw()
to send plain text messages, or create a mail view to enhance the appearance of the message. Carbon
library to check the expiration time of the token. After the verification is successful, use Auth::login()
to log in to the user and delete the used token. Through the above steps, you can implement a safe and reliable password-free login system in the Laravel application, providing users with a more convenient and safe login experience. Remember to adjust the token expiration time and other settings according to your actual needs. For complete code and more detailed steps, please refer to the complete code link you provided.
The above is the detailed content of Let's Kill the Password! Magic Login Links to the Rescue!. For more information, please follow other related articles on the PHP Chinese website!