Laravel 5.6 скачать файл ajax - PullRequest
0 голосов
/ 13 июня 2018

У меня есть REST API в Laravel 5.6

Пользователи могут загружать свой файл в непубличную папку.

Моя проблема в том, что теперь я хочу позволить пользователю загрузить файлтолько если токен JWT действителен и если у пользователя есть необходимые привилегии.

Мой действительный код следующий:

jquery:

$.ajaxSetup({
    headers: {
        'Authorization': 'Bearer ' + token
});

$.get('/api//download?' + $.param({
     file: encodeURIComponent(fileNonPublicPath) //e.g. company_id/file.pdf
}))
.done((data) => {
     console.log('file content', data);
})
.fail((err) => {
      console.error(err);
});

Контроллер Laravel:

$file = urldecode($request->input('file'));
$user = JWTAuth::toUser($request->token);
if(checkUserRole($user,$file){
   $pathToFile = Storage::disk('documents')->getDriver()->getAdapter()->applyPathPrefix($file);
   $finfo = finfo_open(FILEINFO_MIME_TYPE);
   $mime = finfo_file($finfo, $pathToFile);
   finfo_close($finfo);
   $headers = array('Content-Type' => $mime,);
   return response()->download($pathToFile, 'originalfilename', $headers);
}
return response()->json([], 403); //forbidden

Этот код работает нормально, за исключением того, что браузер получает содержимое файла в ajax, а затем пользователь не может его загрузить.

Какое решение не ставит под угрозу безопасность хранимогофайлы

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Я решил это, используя следующее решение:

в файле javascript:

// onclick callback:
window.location = '/download?' + $.param({
   token: encodeURIComponent(STRING_TOKEN),
   file: encodeURIComponent(file)
});    

Создайте новый неохраняемый маршрут в web.php

Route::get('/download', 'UploadController@download');

В UploadController:

$file = urldecode($request->input('file'));
$token = urldecode($request->input('token'));

//This doesn't work
// $user = JWTAuth::toUser($token);

// Then I used the same lib that JWTAuth uses to encode/decode the token
$secret = config('jwt.secret');
$jws = SimpleJWS::load($token);
if (!$jws->isValid($secret)) {
    return response()->json([], 401); // unauthorized
} 
$payload = $jws->getPayload();
$userId = User::find($payload["user"]["id"]);

$user = App\User::find($userId);
if(checkUserRole($user,$file){ 
   $pathToFile = Storage::disk('documents')->getDriver()->getAdapter()->applyPathPrefix($file);
   $finfo = finfo_open(FILEINFO_MIME_TYPE);
   $mime = finfo_file($finfo, $pathToFile);
   finfo_close($finfo);
   $headers = array('Content-Type' => $mime,);
   return response()->download($pathToFile, 'originalfilename', $headers);
 }
 return response()->json([], 403); //forbidden

Это должно быть достаточно безопасно.

0 голосов
/ 13 июня 2018

Вам необходимо загрузить поток, если это не файл.response->streamDownload()

Из документов :

Иногда вы можете захотеть превратить строковый ответ данной операции в загружаемый ответ без необходимости писатьсодержимое операции на диск.Вы можете использовать метод streamDownload в этом сценарии.Этот метод принимает в качестве аргументов обратный вызов, имя файла и необязательный массив заголовков:

return response()->streamDownload(function () {
echo GitHub::api('repo')
            ->contents()
            ->readme('laravel', 'laravel')['contents'];
}, 'laravel-readme.md');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...