Hello.
I would like my users to be able to upload files.
No one should be able to see those files unless they are logged in.
I am aware of Sending Files, but that would require a lot of extra code (helpers, etc)
It must be a way of intercept requests to (for example) webroot/private/ and response with a custom view instead if not logged in.
Is this possible? What would be the best practice?
Edit:
I’be been reading about this but have not seen any CakePHP specific.
I could create an .htaccess inside /webroot/private that redirects all trafic to a Controller method that check if user is logged and if so Send File. Is this OK?
Edit2:
I have tried several .htaccess configurations with no luck
webroot/.htaccess
is overriding webroot/private/.htaccess
no matter what I try:
Try1:
#webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !^private
RewriteRule ^ index.php [L]
</IfModule>
Try2:
#webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^private
RewriteRule ^ index.php [L]
</IfModule>
Try3:
#webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule %{REQUEST_FILENAME} ^private - [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Try4:
#webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule %{REQUEST_URI} ^private - [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
All those while also having:
#webroot/private/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^ /file/?request_url=%{REQUEST_URI} [L]
</IfModule>
Edit3:
Nevermind… I was using bin/cake server
. That’s why .htaccess was not working.
The thing is that now I’m using Apache and a virtualHost and still can’t get this to work.
I need help
Thanks!
What you could do is something like this in your .htaccess
:
# webroot/private/.htaccess
deny from all
Then, make a seperate controller:
namespace App\Controller;
use App\Controller\AppController;
use Cake\Http\Exception\{
ForbiddenException,
NotFoundException
};
class PrivateFileController extends AppController {
public function serve($file) {
// Check if the user is logged in
// ... Do your own required checks here
if(!$this->Auth->user()) throw new ForbiddenException('Please login to access this download');
// Build the filepath
$fileName = 'myfile.pdf';
$localPath = WWW_ROOT . DS . 'private' . DS . $fileName;
// Make sure the file exists
if(!\file_exists($localPath)) throw new NotFoundException('File not found');
// Serve the file
return $this->response
->withFile($localPath);
}
}
and finally, add the required route:
$route->get(
'/private/:file',
['controller' => 'PrivateFiles', 'action' => 'serve']
)->setPass(['file']);
note: Doing it this way is pretty inefficient
Thanks.
The following changes finally worked for me.
*See notes at the end
#/webroot/private/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^ /index.php [L]
</IfModule>
#/config/routes.php
$routes->scope('/', function (RouteBuilder $builder) {
...
$builder->connect('/private/:path', ['controller' => 'Private', 'action' => 'serve'])->setPass(['path']);
...
});
#/src/Controller/PrivateController.php
class PrivateController extends AppController
{
public function serve($path) {
// NOT NEEDED: I already check if logged in AppController::beforeFilter
//if(!$this->UserAuth->isLogged()) throw new ForbiddenException;
$localPath = WWW_ROOT . DS . 'private' . DS . $path;
// NOT NEEDED: see below
// if(!file_exists($localPath)) throw new NotFoundException;
// This method already throws NotFoundException if file does not exist.
return $this->response->withFile($localPath);
}
}
Anyway I changed my mind.
The project I’m working on will have Proceedings
associated with Users
and Files
. Hence I’ll make a FileHelper
and FilesController
will read file’s path from database and check it’s permissions per user. The folder won’t be inside webroot. Also, I won’t need custom routes. Maybe I’ll cache that table. Anyway I don’t care about speed while accesing private files.
1 Like