React JS authentication with Laravel API

We want to create a consumer web app for our API developed using Laravel Passport and Dingo API. Laravel has it’s built in webpack for Vue and ReactJS so we can nicely integrate our client app into existing project.

Result

Here you can find final updated result containing views for:

  • Login
  • Register
  • Forgot password (2 steps)

https://github.com/danielcrt/laravel-reactjs-passport-authentication

Setup

Setup ReactJS inside Laravel project.

 php artisan preset react 

This will remove unnecessary files and prepare the project structure for a React app. You can see in your root directory a file webpack.mix.js where are defined the paths for compiled folders and files.

 
mix.react('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');

So all JS/JSX files from public/js will be compiled to app.js. The same will happen for CSS files.

We want all routes to be handled by React so in routes\web.php we must have:

View

 
Route::view('/{path?}', 'home')
->where('path', '.*')
->name('react');

This is telling Laravel that for all routes it should return the home view found in resources\views\home.blade.php. In this file it is important to include our compiled CSS and JS files.

<head>
...
<link rel="stylesheet" href="{{ asset("css/app.css") }}" type="text/css">
</head>
...

<script type="text/javascript" src="{{ asset("js/app.js") }}"></script>
</body>

Show me React stuff

In our resources\js\app.js the bootstrap.js file is required by default. And along that we should require our entry point into the app. In bootstrap file are included jQuery library and bootstrap js files. If you don’t plan to use them you can remove these to lower the build size.

Below that you have some important lines adding X-Requested-With and X-CSRF-TOKEN headers to axios. If you plan not making requests using axios than you have to handle the by your own. You can prepare the CSRF token for later use in Javascript adding following lines to your view:

<script>
window.Laravel = {!! json_encode([
'csrfToken' => csrf_token(),
]) !!};
</script>

We have used Redux in order to have access to user’s state all over the app so we wrapped our application in a Providerin js\components\App.jsx.

In js\helperswe have added withCredentials = true to axios configs. This will ensure that the authentication cookie will always be send back to the server. In order to handle the case when user wants to access protected routes without being authenticated we created a interceptor which will remove the local stored variable which tells us if user is logged in (for client side usage) and redirect him to home page.

axios.defaults.withCredentials = true; 

axios.interceptors.response.use(
response => response,
(error) => {
if (error.response.data.status_code === 401) {
// we already know from the server that user is no longer logged in
// just delete the local field
localStorage.removeItem(GlobalConstants.USER_KEY);
history.push('/');
}
return Promise.reject(error);
});

Wrap in up

That’s pretty much it. I feel these were the key elements which could save your development time.

If you’d like me to detail more the project structure and components just let me know in comments section.

Join the Conversation

Nice job. I actually want to capture the essential idea on how to use Laravel Passport from which the APIs are consumed by React app in the frontend.
I find your version contains a lot of refactoring both in backend and frontend that may confuse relative new guys like me. But alright, overall I can grasp the essential idea, although I couldn’t pay attention to details of the Redux parts, because I am still lack in Redux.
But when I try the app in Chrome by providing my url : http://localhost/mylaravelprojects/passportauth2/public/
it results in a blank page.
When I open DevTools, there is a warning :
DevTools failed to parse SourceMap: http://localhost/mylaravelprojects/passportauth2/public/js/react-router.js.map
I use React-Router version 5, because with version 4, it also resulted a blank page, but with different warnings which related to the use of componentWillMount() in React-Router version 4.

Thanks for your feedback Alexander!
You are right. There are lot of refactoring in there, some taken from the referenced repository.
Also the code regarding Redux is a bit clumsy.
I am preparing a new post with a simplified authentication without using Passport. Passport is usually too much for small/medium applications.
So the forthcoming post might fit better for you as the code will be cleaner.

In order to start the app you have to run in command line: php artisan serve and run your project at: localhost:8000

Thanks a lot for this article it’s really helpful. I have just one question. What is the purpose of
PERSONAL_CLIENT_ID=1
PERSONAL_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PASSWORD_CLIENT_ID=2
PASSWORD_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

in the .env file? And should I set them up from oauth_clients table?

When you install Passport in your project, using: php artisan passport:install
It will generate you those secret keys which must be stored in .env file. Those are used by Laravel Passport under the hood.

Your email address will not be published.