Laravel default authentication with Vuejs, serve spa only after login

Viewed 1271

I'm doing a SPA with the default Laravel scaffolding:

// Generate basic scaffolding...
php artisan ui vue

// Generate login / registration scaffolding...
php artisan ui vue --auth

This gives us a good starting point with Laravel and Vuejs. It works as expected except for the fact that I would want to serve the SPA, so the .js files, only after user logged in. This requires also to remove the javascript files from the public folder otherwise people would still be able to access the content (not the data of course because it is loaded only for logged in user because of protected routes).

So what I would want to do is protect the resources in the same way you would do to access database data behind auth routes. That wouldn't be enough since I also need to move the created js files made of vue files out of the public folder. If I am not mistaken that happens within webpack?

Best Regards Pouissante

4 Answers

In order to cover your needs, you should have a login page where your users will be able to enter their credentials. Up to that point you have not given any access to the rest of your files. When the user logs in, another action should be called in order for your SPA application to be retrieved from the user.

In any case, I would strongly recommend NOT to have any major business logic in your Front-end js code since the business logic should be calculated server side in order not to be publicly available.

EDIT: To answer your comment, you do not need to configure webpack for this. You can simply have a controller/action which returns the files for the login page ONLY, another action which handles the login credentials of the user and if the user has been granted access, only then you send your SPA application files for your user to be able to view it.

You could easily wrap the JS files you do not want to have publicly available served via PHP file, and those JS files should not be in any public folder..

So moving the files out of ./public/ and to another folder at the same level as public,

and then have Laravel serve a specific Controller -> route, which will output your hidden JS only when PHP checks the credentials of the logged in user.

I'll assume that you want to output your build files to storage/app/build

  • Update your webpack.mix.js

     const fs = require('fs');
     const path = require('path');
     const mix = require('laravel-mix');
    
     const publicPath = 'storage/app/build';
    
     mix.setPublicPath(publicPath)
       .js('resources/js/app.js', 'js')
       .sass('resources/sass/app.scss', 'css');
    
     if (mix.inProduction()) {
       mix.version();
     }
    
     mix.then(function () {
       const src = path.resolve(__dirname, `${publicPath}/mix-manifest.json`);
       const dest = path.resolve(__dirname, 'public/mix-manifest.json');
    
       fs.copyFileSync(src, dest);
       fs.unlinkSync(src);
     });
    
  • Add this route into routes/web.php

     Route::get('/{path}', function (string $path) {
         try {
             return response()->file(storage_path('app/build/'.$path));
         } catch (\Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException $e) {
             abort(404);
         }
     })
       ->where('path', '^(js|css)/.*\.(js|css)$')
       ->middleware('auth');
    

I don't know how your question is related to the issue you explained but I'll explain about it.

Hiding JS File or any files it's not possible because no matter how people always can scrape your page and find it, this is the Front-End problem after all, there was some idea like how EA-Games did in their one of the projects which they put resources into a HTML file then tried to import it with HTML tag in main file, so with this, when someone wanted to access to CSS elements or JS files, all of them was Pre-rendered in HTML file but without mentioning how. I'm not telling you can do this or either but here's one of the ideas that people try to do but after some updates, they removed it. and this was belong to one of my courses which we was trying to explain all type of including resources in HTML files.

So whatever you do, people can find and read your things even Minify JS and CSS can be easily Unminify and become readable.

Now about your question, Laravel default authentication, i might say there are so many ways, there's not a default way for Laravel/Vue, there's a default way for Laravel and people use it that's all. Passport, Sanctum or JWT are the popular way that most people rely on it, which I'll recommend to search for their main idea of how their work, then chose one of them. for spa people mostly chose JWT, ofc you can use other and just simply pass auth()->user() to your blade, but after all it's really depend on what you gonna do after all in spa, how you wanna maintain your basic idea of securing app and more...

Good Luck.

Related