问题
Inside my app, exist a route group called admin
, any route inside this group call two resources: public/css/admin.css
and public/js/admin.js
, but any unauthenticated user has access to these files. How can I include these files inside the Auth Middleware?
My admin routes:
Route::group(['prefix' => 'admin', 'middleware' => ['auth']], function () {
Route::get('/', 'Admin\IndexController@index')->name('panel');
Route::group(['prefix' => 'users'], function() {});
Route::group(['prefix' => 'settings'], function() {});
Route::fallback('Admin\ExceptionController@exception');
});
My resources links:
http://localhost:3000/css/admin.css
http://localhost:3000/js/admin.js
My resources links should be:
http://localhost:3000/admin/css/admin.css
http://localhost:3000/admin/js/admin.js
If I just create the folder admin
inside the public
folder I just got a 403 error...
What can I do about it?
回答1:
Update: Now we'll use storage instead of public directory.
Although I agree that you should not have any sensitive info in your css/js files but if you really want to serve the files to authenticated users you can do it with this work around.
NOTE: I have made the project publicaly avaiable on git so you can clone from there if you want. Git Repo
- Create a directory for admin assets with permission
755
- Create a helper function to serve admin assets.
- Make the helper function available in blade.
- Link the assets using the helper function in order to first authenticate and then serve the file.
Basic Idea:
- The basic idea is to have a directory which no one can access via browser.
- Authenticate the user
- Copy the files from protected directory.
- Paste the files in a new directory (in storage) only associated with the authenticated user.
- Delete the associated directory on user logout.
Implementation:
- Created a directory called
admin_assets
in public directory. - Change the permission of the directory to
755
. - Created a helper class named
CommonHelper
, and write functions to serve and delete admin assets. - Served the assets with these helper functions as following:
<link href="{{ asset( CommonHelper::serveAdminAssets('app.css', '/css/') ) }}" rel="stylesheet">
- Deleted the files at logout.
Finally, as far as the user is logged in the files will be available for him/her, all files will be deleted from the folder once the user logs out.
CommonHelper class:
<?php
/**
*
*/
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
class CommonHelper {
public static function serveAdminAssets($fileName, $filePath) {
if( Auth::check() ) {
$adminAssetsBasePath = public_path().'/admin_assets';
$source = $adminAssetsBasePath.$filePath.$fileName;
$destDir = 'public/'.Auth::user()->id.$filePath;
$dest = $destDir.$fileName;
Storage::put($dest, file_get_contents($source));
return Storage::url($dest);
} else {
return '';
}
}
public static function removeAdminAssets($id) {
$destDir = storage_path('app/public/'.Auth::user()->id);
File::cleanDirectory($destDir);
File::deleteDirectory($destDir);
}
}
?>
Notes:
Remember, if you are using the local driver, all files that should be publicly accessible should be placed in the storage/app/public directory. Furthermore, you should create a symbolic link at public/storage which points to the storage/app/public directory. Docs
Before deleting a directory you should empty it first.
回答2:
I suppose you are using it because you don't want unauthenticated users to know the contents of these css/js files. You shouldn't have any sensitive information in your css/js files, so there is no problem on serving them.
Otherwise, if you want to limit access to a file you should make the file download through PHP. For example you could have the file outside you public folder and make it conditional downloadable through a method that gets file contents and serves for download.
You should can make that public admin folder though, check file permissions and file ownership.
回答3:
Here is an example that you can apply.
Store your assets in storage
directory.
then you can check whether it is an admin or Not.
In your view you can u can inject the Admin Assets Like.
<script>
{!! \Storage::disk('urdisk name')->get('admin.js'); !!}
</script>
for your css you can
<style>
{!! \Storage::disk('urdisk name')->get('admin.css'); !!}
</style>
Hope this helps
回答4:
For applying auth
to the asset files you need to go through from the laravel, not by accessing the files using full path, you need to access css/js files via route so that laravel will be able to apply auth on each files inside route group.
P.S Files must be saved inside storage folder, i-e storage/admin.css
Updated route group
Route::group(['prefix' => 'admin', 'middleware' => ['auth']], function () {
Route::get('/', 'Admin\IndexController@index')->name('panel');
Route::get('{file}', 'StaticFileController@serveFile');
Route::group(['prefix' => 'users'], function() {});
Route::group(['prefix' => 'settings'], function() {});
Route::fallback('Admin\ExceptionController@exception');
});
Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
Use Response;
use App\Http\Requests;
class StaticFileController extends Controller
{
public function serveFile ($file)
{
$storagePath = storage_path($file);
$mimeType = mime_content_type($storagePath);
if( ! \File::exists($storagePath)){
return view('errorpages.404');
}
$headers = array(
'Content-Type' => $mimeType,
'Content-Disposition' => 'inline; filename="'.$file.'"'
);
return Response::make(file_get_contents($storagePath), 200, $headers);
}
}
Now your resources links would be
http://localhost:3000/admin/css/admin.css
http://localhost:3000/admin/js/admin.js
Hope this helps
来源:https://stackoverflow.com/questions/48896224/laravel-include-assets-on-middleware-auth