Protect public folders and files only for guests

Hi, I protected the folder from external access by putting a .htaccess file and the “deny from all” rule in it, but now not even my authenticated users can access those contents. Any suggestions ?

thanks

As you have discovered, ‘Deny from all’ means just that … nobody can access anything.
I think you have two options:

  1. you use an authentication method that is supported by the HTTP server (for instance, Basic Auth) and configure your resources to be accessible by authenticated users (if you’re using Apache, look up AuthUserFile, AuuthGroupFile, AuthType)
  2. have php handle the access, by verifying that the user is authenticated and then reading and sending the content to the user (this may end up not being very efficient, if there are many files that need to be processed for each request).
    Before you proceed, maybe think about why you want to protect those resources. Public folders are supposed to be … public :grinning:

hi enderw thanks for the answer, in reality the files in question are only for internal use, i.e. among users logged in to the application, but I don’t have an accessControl that manages the opening or access to these files in the application I point them with simple links, so even the guest user if he knows the url can open them and I would like to avoid this, I avoided it thanks to the directives placed inside the .htaccess file but these are too restrictive now no one can access not even the users logged into the application.

As enderw says in his second option, you can create action to decide if a user could view the image.

  • Create a folder inside @app folder structure (at same level that the models, controllers and views folders). This folder will not be accessible from web, so you don’t need the deny from all directive.
  • Then use a controller action to decide if user can access to image:
  • Instead using links to folder in view, use the action URL.

example in view:

echo Html::a('Click to download image',['showimg','imgname' => 'image1.jpg']);

And in controller:

public function actionShowimg($imgname){
  $pathToImagesFolder = '@app/images'; 
   if (!Yii::$app->user->isGuest) {
      return Yii::$app->response->sendFile("$pathToImagesFolder/$imgname", $imgname, ['target' => "_blank"]);
   } else {
      return $this->redirect(['login']);
}

(Note: I’ve not checked syntactic errors)

See https://www.yiiframework.com/doc/api/2.0/yii-web-response#sendFile()-detail