A Comprehensive Guide To Laravel Authentication

Mar 22, 2023
Laravel Queue

The ability to authenticate is among web application's most important and essential capabilities. Web frameworks like Laravel offer a variety of ways for users to sign in.

You can implement Laravel authentication features swiftly and secure. But, implementing these functions incorrectly could be dangerous because malicious individuals could exploit them.

This tutorial will help you understand all you need to know before you can begin to use your chosen Laravel authentication techniques.

Read on!

An Intro To Laravel Authentication

Our authentication settings are set in a file named config/auth.php. This file contains a number of options to tweak and modify Laravel's authentication behavior.

First, you have to determine the defaults for authentication. This option controls your application's default security "guard" and password reset options. The default settings can be changed as required, but they're a perfect start with the majority of apps.

Next, you define authentication guards for your application. Here, our default configuration makes use of session storage, as well as the Eloquent user provider. Each authentication driver comes with a user provider.

return [
 /* 
 Defining Authentication Defaults 
 */
 
 'defaults' => [
 'guard' => 'web', 
 'passwords' => 'users',
 ],
 
 /*
 Defining Authentication Guards
 
 Supported: "session"
 */
 
 'guards' => [
 'web' => [
 'driver' => 'session',
 'provider' => 'users',
 ],
 ],
 
 /*
 Defining User Providers
 
 Supported: "database", "eloquent"
 */
 
 'providers' => [
 'users' => [
 'driver' => 'eloquent',
 'model' => App\Models\User::class,
 ], 
 
 // 'users' => [
 // 'driver' => 'database',
 // 'table' => 'users',
 // ],
 ],
 
 /*
 Defining Password Resetting
 */
 
 'passwords' => [
 'users' => [
 'provider' => 'users',
 'table' => 'password_resets',
 'expire' => 60,
 'throttle' => 60,
 ],
 ],
 
 /*
 Defining Password Confirmation Timeout
 */
 
 'password_timeout' => 10800,
 ];

Then, we ensure that each authentication driver has the user's provider. It defines how users are retrieved from your database or any other storage methods to preserve the user's information. It is possible to configure several sources for each model or table in the event that you have more than one model or user tables. The sources can be assigned to other authentication guards you have defined.

Users may also want to change their passwords. In this case, you could set multiple password reset settings when you have more than one table or model in the application , and wish to have separate settings based on the specific user types. The expiration period is the number of minutes each reset token will be valid. The security function keeps tokens short-lived, so they are less likely to be guessed. This can be changed as needed.

In the end, it is your responsibility to determine the time before a password confirmation times out in which case the user will be asked to enter their password again through the confirmation screen. By default, the timeout will last for 3 hours.

Different types of Laravel Authentication Methods

Password Based Authentication

A basic way to authenticate a user, it is still used by thousands of organizations, but considering current development the method is becoming outdated.

Vendors are required to enforce sophisticated password implementations and ensure little friction for the user.

The process is fairly simple, the user inputs the name and the password, and, if within the Database it is found to be any match between these two items, the server chooses to verify the request and let the user use the resources for a predefined period of time.

Token-Based Authentication

The method is employed when the user is issued an individual token after verification.

With this token, users can gain access to relevant sources. This privilege remains in effect until the expiration date of the token.

If the token is activated it does not need to enter a username or password, but when they retrieve a new token, both are needed.

Tokens are extensively used across a variety of scenarios since they are stateless entities that include all authentication information.

Offering a method to distinguish token generation and token verification provides vendors with a great deal of freedom.

Multi-Factor Authentication

The name indicates the idea is to use at least two authentication methods, elevating the level of security that it offers.

It is typically implemented using a password, after which the user is provided with a verification number on their phone. Companies that implement this technique should look for false positives and network outages, which can cause major issues when expanding quickly.

How Do I Implement Laravel's Authentication

Manual Authentication

Starting with registering users and creating the needed routes within routes/web.php .

We will create two routes, one to view the form , and another to sign up:

use App\Http\Contrllers\Auth\RegisterController;
 use Illuminate\Support\Facades\Route;
 
 /*
 Web Routes 
 
 Register web routes for your app's RouteServiceProvider 
 in a group containing the "web" middleware
 */
 
 Route::get('/register', [RegisterController::class], 'create']);
 
 Route::post('/register', [RegisterController::class], 'store']);

And create the controller needed for these:

php artisan make controller Auth/RegisterController -r

Now update the code in the following manner:

namespace App\Http\Controllers\Auth;
 
 use App\Http\Controllers\Controller;
 use illuminate\Htpp\Request;
 
 class RegisterController extends Controller
 
 public function create()
 
 return view('auth.register');
 
 
 public function store(Request $request)
 
 
 

The controller is now empty and it returns a view that you can register. We can create that view within the resources/views/auth and name register.blade.php. register.blade.php.

After everything is in place now, it is time to visit our or register route, and then fill out the form below:

public function store(Request $request)
 
 $credentials = $request->only('email', 'password');
 
 if (Auth::attempt($credentials, $request->filled('remember'))) 
 $request->session()->regenerate();
 
 return redirect()->intended('/');
 
 
 return back()->withErrors([
 'email' => 'The provided credentials do not match our records. ',
 ]);
 

We now have a form that a user can complete and get the required data and then collect the users' data, validate it, and then put it into the database to ensure that everything is okay. This is where you need to utilize a database transaction to verify that the information that you input is correct.

We'll use Laravel's request validation feature to make sure that all three credentials are required. It is imperative to ensure that it's in the correct address format, and that it is unique within the user database and the password is verified and contains a minimum of 8 characters:

namespace App\Http\Controllers\Auth;
 
 use App\Http\Controllers\Controller;
 use Illuminate\Foundation\Auth\User;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Hash;
 
 class RegisterController extends Controller
 
 public function store(Request $request)
 confirmed
 
 public function create()
 
 return view('auth.register');
 
 

After our input has been verified, anything that goes against the validation process will result in an error. It will then be displayed in the form:

If we've created an account for a user using the Store method, we want to log in to the account. There are two methods in that we could do this. It is possible to do this manually or by using the the Auth facade.

When a user signs into the system, we shouldn't return them to the Register screen. Instead, they should be directed to a different webpage, for example, a homepage or dashboard. We'll do that to do here:

namespace App\Http\Controllers\Auth;
 
 use App\Http\Controllers\Controller;
 use App\Providers\RouteServiceProvider;
 use Illuminate\Foundation\Auth\User;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Hash;
 
 class RegisterController extends Controller
 
 public function store(Request $request)
 confirmed
 
 public function create()
 
 return view('auth.register');
 
 

And now that we have a user registered and logged in and -n, we must ensure that he is able to safely sign out.

Laravel proposes we disable the session then re-create the token for security after a logout. That's exactly what we are going to accomplish. The first step is to create an entirely new logout route using LogoutController's destroy method:

use App\Http\Controllers\Auth\RegisterController;
 use App\Http\Controllers\Auth\LogoutController;
 use Illuminate\Support\Facades\Route;
 
 /*
 Web Routes
 
 Here is where you can register web routes for your application. These
 routes are loaded by the RrouteServiceProvider with a group which
 contains the "web" middleware group. Create something amazing! */
 
 Route::get('/register', [RegisterController::class, 'create']);
 
 Route::post('/register', ['RegisterController::class, 'store']);
 
 Route::post('/logout', [Logoutcontroller::class, 'destroy'])
 ->middleware('auth');

Passing the logout via"auth," the "auth" middleware program is very crucial. The user should be unable access the service when they're not logged in.

Now, create a controller as we did earlier:

php artisan make:controller Auth/LogoutController -r

It is possible to ensure that the request will be received as a parameter to the destroy method. We sign out the user using an Auth facade, then invalidate the session and, regenerate the token, then redirect users to the home page:

namespace App\Http\Controllers\Auth;
 
 use App\Http\Controllers\Controller;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 
 class LogoutController extends Controller
 
 public function destroy(Request $request)
  
 Auth::logout();
 
 $request->session()->invalidate();
 
 $request->session()->regenerateToken();
 
 return redirect('/');
 
 

Remembering Users

Most, if not all modern websites offer a "remember me" checkbox when you sign in to their forms.

If we would like to add the "remember me" feature, we can use a boolean as the second argument to the try method.

If the token is valid, Laravel will keep the person authenticated for a long time or until they manually logged out. The table of users should contain the strings forget_token (this is the reason we generate the tokens) column. This is where we will keep our "remember me" token.

The default migration for users already include it.

To begin, you need to include to your form the Remember Me field on your form:

Then, you can get the credentials from the request and then use them on the attempt method of the Auth facade.

If the user's name is recognized, we'll sign him in and redirect him to our homepage. Otherwise, we will throw an error.

public function store(Request $request)
 {
 $credentials = $request->only('email', 'password');
 
 if (Auth::attempt($credentials, $request->filled('remember'))) 
 $request->session()->regenerate();
 
 return redirect()->intended('/');
 
 
 return back()->withErrors([
 'email' => 

Resetting Passwords

The majority of web-based applications offer options for users to reset their passwords.

We will make another option for the forgotten password and then create the controller in the same way as we did. We will also create a new route to that reset password button, which has the token needed that will be used throughout the entire process

Route::post('/forgot-password', [ForgotPasswordLinkController::class, 'store']);
 
 Route::post('/forgot-password/token', [ForgotPasswordController::class, 'reset']);

Inside the store method, we will take the email address from the request and confirm it in the same manner like we would normally do.

After this, we can make use of to use the SendResetLink method that is accessible from the password facade.

Then, as an response, we'd like to return the status If it has succeeded in sending the link , or any other error:

namespace App\Http\Controllers\Auth;
 
 use App\Http\Controllers\Controller;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Password;
 
 class ForgotPasswordLinkController extends Controller
 
 public function store(Request $request)
 
 $request->validate([
 'email' => 'required
 

Now that the reset link has been sent to the user's email, we should take care of the process after that.

We will get the token, email address, as well as the new password when you submit the email and verify them.

Following this, we are able to apply the reset option using the password façade to leave Laravel manage everything else behind the scenes.

It is always a good idea to have a password hash in order to protect it.

Then, we will check whether the password has been reset, and if it were, we will redirect users to the login screen , with the message "Success. In the event that it was not reset, we show an error that it could not be reset:

namespace App\Http\Controllers\Auth;
 
 use App\Http\Controllers\Controller;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Hash;
 use Illuminate\Support\Facades\Password;
 use Illuminate\Support\Str;
 
 class ForgotPasswordController extends Controller
 
 public function store(Request $request)
 
 $request->validate([
 'token' => 'required',
 'email' => 'required
 

Laravel Breeze

Laravel Breeze is an easy solution to Laravel authentication features including registration, login, password reset, email verification, and password confirmation. You can use it to integrate authentication into your brand new Laravel application.

Installation and Setup

After you've created your Laravel application, all you have to do is set up your database, perform your migrations, then install the laravel/breeze application through composer:

composer require laravel/breeze -dev

After this, run these steps:

php artisan breeze:install

Which will publish your authentication views and routes, controllers, and any other resources it makes use of. After this step you will have full control of everything that Breeze gives you.

Now we have to render our frontend application, so we will install our JS dependencies (which utilize @vite):

Install npm

:

npm run dev

Once you have logged in, the login and register links must be displayed on your home page, and everything should work smoothly.

Laravel Jetstream

Laravel Jetstream enhances Laravel Breeze by adding useful functions and other frontend stacks.

It provides the ability to login, register and email verification. It also provides Two-factor authentication and session management. API support via Sanctum and team administration.

There is a choice between Livewire or Inertia on the frontend when installing Jetstream. The backend makes use of Laravel Fortify that is a frontend agnostic, "headless" authentication backend for Laravel.

Installation and Installation

We'll install it via the composer of our Laravel Project:

composer require laravel/jetstream

After this, we will use the jetstream install php artisan jetstream] command, which accepts [stackas options such as Livewire and Inertia. Then, you can use the option -team option to activate the feature for teams.

This will also install Pest PHP for test purposes.

Finally, we need to create the front end of our application by using these methods:

npm install
 npm run dev

Laravel Fortify

Laravel Fortify is a backend authentication system that's frontend independent. It's not necessary to utilize Laravel Fortify to implement Laravel's authentication capabilities.

It's also used for beginning kits such as Breeze as well as Jetstream. Fortify can be used Fortify standalone that is an implementation of the backend. If you decide to run it as a as a standalone application, your frontend has to use Fortify's routes to call them.

Installation and Installation

We are able to install Fortify through composer:

composer require laravel/fortify

The next step is to make available Fortify's sources:

php artisan vendor:publish -provider="Laravel\Fortify\FortifyServiceProvider"

After this, we will create a new app/Actions directory in addition to the new FortifyServiceProvider, configuration file, and database migrations.

Finally, run:

php artisan migrate

Or:

php artisan migrate:fresh

Then your Fortify is all set to go.

Laravel Socialite

Installation

It is possible to install it via composer:

composer require laravel/socialite

Configuration and Use

Once we've installed it, we have to add the credentials for the OAuth provider our application relies on. The credentials will be added to config/services.php for each service.

In the configuration you will need to compare the key with the previous services. Some of those keys comprise:

  • Facebook
  • Twitter (For OAuth 1.0)
  • Twitter-Oauth-2 (For OAuth 2.0)
  • linkedin
  • Google
  • Github
  • Gitlab
  • bitbucket

A service configuration could be as follows:

'google' => [
 'client_id' => env("GOOGLE_CLIENT_ID"),
 'client_secret' => env("GOOGLE_CLIENT_SECRET"),
 'redirect' => "http://example.com/callback-url",
 ],

Authenticating Users

To accomplish this there are two paths, one that will redirect the user's request to an OAuth service provider

use Laravel\Socialite\Facades\Sociliate;
 
 Route::get('/auth/redirect', function () 
 return Socialite:;driver('google')->redirect();
 );

And one for the callback from the provider after authenticating:

use Laravel\Socialite\Facades\Socialite;
 
 Route:;get('/auht/callback', function () 
 $user = Socialite:;driver('google')->user();
 
 // Getting the user data
 $user->token;
 );

Socialite provides the redirect method while the facade redirects the user to the OAuth provider. The user method analyzes the request and retrieves user information.

After we have received our user, we have to confirm that it is present in our database. If it does, we must authenticate it. If it does not exist the database is not available, then we'll make a new entry to represent the user:

use App\Models\User;
 use Illuminate\Support\Facades\Auth;
 use Laravel\Socialite\Facades\Socialite;
 
 Route::get('/auth/callback', function () 
 /*
 Get the user
 */
 $googleUser = Socialite::driver('google')->user();
 
 /*
 Create the user if it does not exist
 Update the user if it exists
 
 Check for google_id in database
 */
 $user = User::updateOrCreate([
 'google_id' => $googleUser->id,
 ], [
 'name' => $googleUser->name,
 'email' => $googleUser->email,
 'google_token' => $googleUser->token,
 'google_refresh_token' => $googleUser->refreshToken,
 ]);
 
 /*
 Authenticates the user using the Auth facade
 */
 Auth::login($user);
 
 return redirect('/dashboard');
 );

If we would like to limit the user's access scopes then we can make use of this scoping method, which we add to the request for authentication. It will combine all the previously identified scopes to the specific one.

Another option is to utilize this method: the setScopes method, which overwrites each else existing scope:

use Laravel\Socialite\Facades\Socialite;
 
 return Socialite::driver('google')
 ->scopes(['read:user', 'write:user', 'public_repo'])
 ->redirect();
 
 return Socialite::driver('google')
 ->setScopes(['read:user', 'public_repo')
 ->redirect();

We now know all the details about how to reach the user's number after the callback Let's take a look at some of the info we can get from it.

OAuth1 user has token as well as tokenSecret:

$user = Socialite::driver('google')->user();
 
 $token = $user->token;
 $tokenSecret = $user->tokenSecret;

OAuth2 gives you a the token, refreshToken as well as expires In:

$user = Socialite::driver('google')->user();
 
 $token = $user->token;
 $refreshToken = $user->refreshToken;
 $expiresIn = $user->expiresIn;

Both OAuth1 as well as OAuth2 have getID GetNickname, getName getEmail, and getAvatar:

$user = Socialite::driver('google')->user();
 
 $user->getId();
 $user->getNickName();
 $user->getName();
 $user->getEmail();
 $user->getAvatar();

And if we want to get user details from a token (OAuth 2) or a token and secret (OAuth 1), sanctum provides two methods for this: userFromToken and userFromTokenAndSecret:

use Laravel\Socialite\Facades\Socialite;
 
 $user = Socialite:;driver('google')->userFromToken($token);
 $user = Socialite::driver('twitter')->userFromTokenAndSecret($token, $secret);

Laravel Sanctum

Laravel Sanctum is a light authenticator system that is suitable for SPAs (Single Page Applications) as well as mobile applications. It lets users create several API tokens with specific scopes. These scopes determine the types of actions allowed by a token.

Usages

Sanctum may be used to provide API tokens to the user without the intricacies of OAuth. Those tokens typically have long expiration times, like years. However, they are able to be changed and cancelled by users at any point.

Installation and Installation and

You can set it up via composer

composer require laravel/sanctum

We also have to make the configuration and migration files:

php artisan vendor:publish -provider="Laravel\Sanctum\SanctumServiceProvider"

After we've created new files for migration and we are ready to transfer the following files:

php artisan migrate  or  php artisan migrate:fresh

How Do I Issue API tokens

Before issuing tokens, our User model should use the Laravel\Sanctum\HasApiTokens trait:

use Laravel\Sanctum\HasApiTokens;
 
 class User extends Authenticable
 
 use HasApiTokens;
 

When we have the user, we can issue a token by calling the createToken method, which returns a Laravel\Sanctum\NewAccessToken instance.

You can use the plainTextToken method in the NewAccessToken instance to see the SHA-256 the plain text of the token.

Strategies and best practices for Authenticating Laravel

Validating Sessions on Other Devices

As we have discussed previously, invalidating the session is essential when a user logs off, however, it should be accessible to every device owned by the user.

This option is typically used when the user changes or alters their password in order to erase their account on another device.

Utilizing the Auth facade, this is an easy process to complete. Given that the method that we're using comes with the auth as well as the auth.session middleware, we can make use of this method to logoutOtherDevices static method of the facade

Route::get('/logout', [LogoutController::class, 'invoke'])
 ->middleware(['auth', 'auth.session']);
 
 
use Illuminate\Support\Facades\Auth;
 
 Auth::logoutOtherDevices($password);

Configuration With Auth::routes()

The method for routes of the Auth facade acts as a helper to generate every route required to enable user authentication.

The possible routes are Login (Get Post, Get), Logout (Post), Register (Get, Post) as well as Password Reset/Email (Get Post, Get).

If you call the method on the facade this will accomplish the following:

public static fucntion routes(array $options = [])
 
 if (!static::$app->providerIsLoaded(UiServiceProvider::class)) 
 throw new RuntimeException('In order to use the Auth:;routes() method, please install the laravel/ui package. ');
 
 
 static::$app->make('router')->auth($options);
 

We're interested in knowing what happens when the static method called on the router. This is a tricky task due to the fact of how facades work however the method called is like this:

/**
Register the usual authentication routes to an application. @param array $options
 @return void
 */
 public function auth(array $options = [])
 
 // Authentication Routes...
 $this->get('login', 'Auth\[email protected]')->name('login');
 $this->post('login', 'Auth\[email protected]');
 $this->post('logout', 'Auth\[email protected]')->name('logout');
 
 // Registration Routes...
 if ($options['register'] ?? true) 
 $this->get('register', 'Auth\[email protected]')->name('register');
 $this->post('register', 'Auth\[email protected]');
 
 
 // Password Reset Routes...
 if ($options['reset'] ?? true) 
 $this->resetPassword();
 
 
 // Email Verification Routes...
 if ($options['verify'] ?? false) 
 $this->emailVerification();
 
 

It generates by default all routes besides the verification email route. It will always generate the Login and Logout routes. However, the other ones we can control via the choices range.

If we wish to allow just login/logout, and not register then we could pass these options arrays:

$options = ["register" => true, "reset" => false, "verify" => false];

Protecting Routes and Custom Guards

We need to ensure that some routes can be accessed only by authenticated users and is easily accomplished through either calling the middleware method on the facade of Route or by using the middleware method in conjunction with it:

Route::middleware('auth')->get('/user', function (Request $request) 
 return $request->user();
 );
 
 Route::get('/user', function (Request $request) 
 return $request->user();
 )->middleware('auth');

This security feature ensures that any incoming request are authenticated.

Password Confirmation

To ensure website security, you often want to confirm the password of a user prior to proceeding with the next job.

It is necessary to define a path from the confirm password view for handling the request. This will confirm and then redirect the user towards their final destination. In addition we ensure that our password appears confirmed within the session. By default, the password is confirmed every 3 hours. the frequency can be altered by modifying the configuration file in config/auth.php:

use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Hash;
 use Illuminate\Support\Facades\Redirect;
 
 Route::post('/confirm-password', function (Request $request) 
 if (!Hash::check($request->password, $request->user()->password)) 
 return back()->withErrors([
 'password' => ['The provided password does not match our records.'] ]);
 
 
 $request->session()->passwordConfirmed();
 
 return redirect()->intended();
 )->middleware(['auth']);

Authenticable Contract

The Authenticable contract located at Illuminate\Contracts\Auth defines a blueprint of what the UserProvider facade should implement:

namespace Illuminate\Contracts\Auth;
 
 interface Authenticable 
 
 public function getAuthIdentifierName();
 
 public function getAuthIdentifier();
 
 public function getAuthPassord();
 
 public function getRememberToken();
 
 public function setRememberToken($value);
 
 public function getrememberTokenName();
 

The interface allows for the system of authentication to interact alongside every "user" class which implements it.

This holds regardless of what ORM or storage layers are used. As a default, Laravel has the App\Models\User that implements this interface, which can be seen in the configuration files:

return [
 'providers' => [
 'users' => [
 'driver' => 'eloquent',
 'model' => App\Models\User::class,
 ],
 ],
 ];

Authentication Events

There are plenty of events which are triggered throughout the authentication procedure.

Depending on your goals, you can attach listeners to those events in your EventServiceProvider.

Quickly Create New Users

Making a user new quickly can be done through the Application User:

$user = new App\User();
 $user->password = Hash::make('strong_password');
 $user->email = '[email protected]';
 $user->name = 'Username';
 $user->save();

or through the static creation method on the User's interface:

User::create([
 'password' => Hash::make('strong-password'),
 'email' => '[email protected]',
 'name' => 'username'
 ]);

Summary

The Laravel ecosystem comes with a variety of basic kits for getting your app up and running with an Authentication system like Breeze or Jetstream. They can be highly customized as the code is created on our side, and we can modify the way we'd like using it as a blueprint should we need to.

There are many security concerns with regards to authentication and its complexities however, all of them can be solved easily through the tools that Laravel offers. The tools can be highly customized and simple to use.

  • Simple setup and management on My dashboard. My dashboard
  • 24/7 expert support
  • The most efficient Google Cloud Platform hardware and network powered by Kubernetes to ensure maximum capacity
  • An enterprise-level Cloudflare integration that improves speed as well as security
  • Global audience reach with up to 35 data centers, and more than 275 PoPs across the globe