Skip to Content
Menu
All Posts

Article

Setting Up Laravel and React.js the Right Way (Using User Authentication)

It's been quite a while since I wrote the initial article here and a lot has changed since then. This article is intended to be an upgraded replica of the initial article with simplicity in focus. ...

Toluwani Adewale 8 min read
Updated

Laravel and React

It's been quite a while since I wrote the initial article here and a lot has changed since then. This article is intended to be an upgraded replica of the initial article with simplicity in focus. 

 

Back-end

In this section, we will be creating APIs for CSRF protection, registration, login, dashboard, and logout, using the following:

  1. PHP — Laravel framework; to build the REST APIs
  2. Docker - Laravel Sail
  3. Laravel Sanctum - SPA Authentication
  4. Laravel Fortify - Disabling Views
  5. Postman - Any API tester of your choice

 

Setting Up Laravel with Sail

Laravel has quite a rich documentation on installation best practices here. We will make use of Sail which is a lightweight command-line interface for interacting with Laravel's default Docker configuration. Simply put, it abstracts all the complexities of setting up a docker application and helps us focus more on development.

We will run the following in our terminal to create a new Laravel project which we'll call laravel-typescript-react-authentication, we'll then navigate into this project and start Laravel Sail in detached mode:

curl -s "https://laravel.build/laravel-typescript-react-authentication" | bash

cd laravel-typescript-react-authentication
 
./vendor/bin/sail up -d

Remember to add laravel-typescript-react-authentication.test to your host file when using the .test domain suffix. 

TIP: If you intend to run multiple Laravel instances on Sail, follow this article to avoid port collisions.

 

Setting Up Laravel Sanctum

We will install Sanctum and make use of its SPA Authentication feature which makes authenticating SPAs quite seamless. Using this feature, we ditch tokens and make use of the web guard - basically cookie-based sessions (which we're typically more used to 😎). Of course, you can use tokens if you want to - it's actually quite easier than SPA Authentication IMO, this article just doesn't cover that 💀.

The documentation for Sanctum is rich and explicit enough and it already ships with the latest Laravel versions, but we will go through the installation process together by running the following:

./vendor/bin/sail composer require laravel/sanctum

./vendor/bin/sail artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

./vendor/bin/sail artisan migrate

Using the commands above, we install Sanctum, publish the configuration file as config/sanctum.php, also the migration file as database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php. We then run the migration.

TIP: You can set an alias for ./vendor/bin/sail so you don't need to type all that every time you need to run a command; This article explains the process for Linux/macOS while this is for windows. I have set my alias as sail.

Next, we will add (or uncomment in recent versions) Sanctum's middleware in the api middleware group in the app/Http/Kernel.php file. The api block ends up looking like this:

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

We need to inform Sanctum about the host/location of our SPA/Frontend. Since the frontend and backend components of our application are under the same domain we wouldn’t necessarily be needing Cross-origin resource sharing (CORS) or those sorts of things. We will add our domain to the key SANCTUM_STATEFUL_DOMAINS at the bottom of .env like this:

SANCTUM_STATEFUL_DOMAINS=laravel-typescript-react-authentication.test

 

Setting Up Laravel Fortify

Laravel Fortify is a frontend agnostic authentication backend implementation for Laravel, a simple definition is that it doesn't offer a Frontend or View layer - its only interest is giving us all of Laravel's authentication logic quite seamlessly. If you prefer to write your own authentication logic manually, kudos to you - you can skip this section 👍🏽.

To install Fortify, run the following:

sail composer require laravel/fortify

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

sail artisan migrate

Although Fortify is agnostic about our frontend layer, it defines routes with the intention that we'd create Views (blade templates) for them. Since we're making use of React, we disable this configuration by changing views to false in our config/fortify.php. That line ends up looking like this:

'views' => false,

For this simple article, we also don't need a couple of the juicy authentication features that Fortify provides such as password resets, profile updates, password updates, and two-factor authentication, so we comment these out in the feautures configuration still within our config/fortify.php:

'features' => [
    Features::registration(),
    // Features::resetPasswords(),
    // Features::emailVerification(),
    // Features::updateProfileInformation(),
    // Features::updatePasswords(),
    // Features::twoFactorAuthentication([
    //     'confirm' => true,
    //     'confirmPassword' => true,
    // ]),
],

We will also ensure we're not forgetting to add the App\Providers\FortifyServiceProvider::class to the bottom of our providers configuration in the config/app.php file:

'providers' => [
    // ... providers,
    
    App\Providers\FortifyServiceProvider::class,
]

Finally, as per convention, we want our API routes to have api prefixes in them. If you list all routes using sail artisan route:list you'd get this:

Route no prefix

We will update the prefix configuration to api in our config/fortify.php as shown below:

'prefix' => 'api',

Now running sail artisan route:list, we get to see that our api routes/endpoints are now properly prefixed as shown in the image below:

Route with prefix

An important digression: There's just one last thing we've gotta do before we can effectively start testing out these endpoints - I do find this issue weird since we've already set views to false.

You see, our authenticated routes (check routes/api.php for api/user) will be protected by Sanctum's authentication guard using middlewares i.e. Route::middleware('auth:sanctum'), if you recall clearly, we're dealing with sessions here. After authentication, Sanctum redirects our request to a home route like it would normally do if we were using views, we need to bypass this by telling it not to but rather continue the request as an API.

To do this, we have to add another small condition && !$request->wantsJson() in the handle  method in app/Http/Middleware/RedirectIfAuthenticated.php  and that ends up looking like this:

public function handle(Request $request, Closure $next, ...$guards)
{
    $guards = empty($guards) ? [null] : $guards;

    foreach ($guards as $guard) {
        if (Auth::guard($guard)->check() && !$request->wantsJson()) {
            return redirect(RouteServiceProvider::HOME);
        }
    }

    return $next($request);
}

 

Setting Up Postman

The most effective way we can go about this is to create a collection in Postman, this is because we've got to store the value of the XSRF-TOKEN cookie in the X-XSRF-TOKEN header to use in consecutive requests; this prevents a CSRF token mismatch - once again 💀, recall that we're using sessions instead of tokens. Postman makes this easy with Pre-request Script.

Now that we've created our collection, we need to create an environment. We can do this by clicking the eye 👁 icon (ensure that No Environment is selected in the dropdown) and then clicking on Add in the Environments action. A new tab titled New Environment is created for us as portrayed below:

Postman: creating an environment

We will add a url variable in our environment with the value of http://laravel-typescript-react-authentication.test as shown in the image below:

Postman: Add environment variables

Note: As you might have noticed, I have already created the necessary API endpoints in the collection which we will go over soon, you can also go ahead and do that. 

Ensure to add the value application/json to Accept key and {{XSRF-TOKEN}} to X-XSRF-TOKEN key in the headers section of each request. Our Pre-request Script will help us automatically set our {{XSRF-TOKEN}} variable in our collection's environment, check out a sample below:

Postman Header Configuration

 

Testing the CSRF Protection API Endpoint

We will proceed to create a new GET request for {{URL}}/sanctum/csrf-cookie, we will then add the following to the Pre-req. (Pre-request Script) tab:

pm.sendRequest({
    url: 'http://laravel-typescript-react-authentication.test/sanctum/csrf-cookie',
    method: 'GET'
}, function (error, response, { cookies }) {
    if (!error) {
        pm.environment.set('XSRF-TOKEN', cookies.get('XSRF-TOKEN'))
    }
})

The snippet above sends a GET request to our csrf-cookie  URL then grabs the XSRF-TOKEN cookie and sets it as a variable in our collection's environment. This will be accessible to every request in our collection. 

Testing the CSRF Protection API Endpoint

 

Testing the Register API Endpoint

We will proceed to create a new POST request for {{URL}}/api/register and test the API endpoint:

Testing the Register API Endpoint

 

Testing the Login API Endpoint

We will proceed to create a new POST request for {{URL}}/api/login and test the API endpoint:

Testing the Login API Endpoint

Note: In the future, you have to always make a request to the CSRF Protection API Endpoint before the Login API Endpoint. We've already done this previously so we can skip it.

 

Testing the Get User API Endpoint

When we access protected or now authenticated endpoints such as the Get User endpoint, Sanctum does this thing where it checks the request for a referrer header. A referrer header is defined as the domain - a link to the page that made the incoming request, simply put, it is the URL of the page that's trying to access an endpoint. This would normally be our domain that we added to the key SANCTUM_STATEFUL_DOMAINS at the bottom of .env when setting up Sanctum.

Luckily for us, we already have that as a {{URL}} parameter in our Postman collection so we update the Header and create a new GET request for {{URL}}/api/user and test the API endpoint:

Testing the Get User API Endpoint

 

Testing the Logout API Endpoint

We will proceed to create a new POST request for {{URL}}/api/logout and test the API endpoint:

Testing the Logout Endpoint

 

Setting Up Web Routes

We wouldn’t be needing much of Laravel’s routing as React comes with quite an awesome routing system, so we replace the contents in our routes/web.php with this:

Route::get('/{all}', function () {
    return view('welcome');
})->where('all', '^(?!api).*$');

The snippet above redirects all URLs to the welcome view except of course the API routes.

 

Front-end

https://toluwaniadewale.com/blog/setting-up-laravel-and-reactjs-the-right-way-using-user-authentication-ii

Responses (3)

Have a question, correction, or another approach? Add your response.

Your name and response will be public.

sss

s

sss

s

ali

ali