Jerimiah Baldwin Jerimiah Baldwin - 1 year ago 77
AngularJS Question

Laravel + Angular: Securing Angular Pages

How do I prevent users not-logged into Laravel session from downloading AngularJS pages?

I have a website with Laravel on the back-end. There is also an AngularJS application which is placed in the folder public/myApp/index.html. .htaccess returns any files referenced so returns the Angular application and all requests for js and css are downloaded without authentication.

What is the best way to prevent the download of all js, html, and css files related to my Angular app (i.e. in the /myApp subdirectories) for all users not authenticated into Larvel session?

Answer Source

None of these options really resolved what I was looking for. What I ended up doing was the following. I am using a 3rd party Angular front-end template (Angulr from ThemeForest) with hundreds of thousands of lines of code and hundreds of different files. A large portion of those files are stylesheets and generic JavaScript libraries (Angular, JQuery, etc.) I don't mind putting that content into the public folder and serving the files to non-authenticated users.

But, the other portion of my files are the modified files. For example, one file has navigation elements that pretty much layout the entire format of my proprietary business system and say a lot about the internal operations of the business. So, something as simple as the navigation html, css, and js is sensitive and should only be served to authenticated users.

What I did was split the public and protected content into identical (or at least similar) directory trees with one located at /public/* and the other located at /storage/app/*. All my non-sensitive content (mostly the template stylesheets and generic JS libraries) goes in the "public" tree while the sensitive content goes in my "storage/app" tree. So for example:

- public --- js ----- someThirdPartyJavaScript.js ----- loginController.js (unprotected) ----- ... --- libs ----- angular.js ----- jquery.js ----- ... --- css ----- unprotectedStyleSheet.css ----- ... --- tpl ----- loginTemplate.html - storage (all protected content goes in this tree) --- app ----- js ------- myApp.js ------- directives --------- myCustomDirective.js --------- businessNavigationDirective.js (sensitive and proprietary) ----- css (for protected css files) ----- libs (for protected libs) ----- tpl (for protected .html files) ------- clientInformationSheet.html (sensitive content indicating the structure of our customer data)

In .htaccess, I used the following rule to basically return any file that exists in the public tree:

    # If the file exists in laravel/public and the URI does not specify ".php" then go get it.
RewriteCond %{DOCUMENT_ROOT}/laravel/public/%{REQUEST_URI} -f
RewriteCond %{REQUEST_URI} !^.*\.php$
RewriteRule ^(.*)$ laravel/public/$1 [L]

.htaccess sends all other requests to be handled by Laravel index.php

Then, I created a Laravel 5.2 route to catch all for routes within my Angular app. Notice that the middleware specifies auth so these files will not be return to the user from the storage directory unless the user has authenticated:

use League\Flysystem\Util\MimeType as MimeType;

Route::any('/{any}', ['middleware' => 'auth', function($uri){
    // Auth::logout();
    $uri = storage_path('app/' . $uri);

    if (!File::exists($uri)){
        return "Path not found.";

    $extension = File::extension($uri);

    if (array_key_exists($extension, MimeType::getExtensionToMimeTypeMap())){
        $mimeType = MimeType::getExtensionToMimeTypeMap()[$extension];  
    } else {
        $mimeType = "text/plain";

    return response(File::get($uri))
        ->header('Content-Type', $mimeType);

}])->where('any', '^MySuperCoolApplicationSubDirectory/.*');

Keeping directory structures pretty similar between "public" and "storage/app" made it really easy to organize which files are sensitive and which are not and the application continued to function as it had before, this time with all sensitive content being blocked from unauthenticated users.