如何为 Laravel 设置文件权限


How to set up file permissions for Laravel?

我正在使用所有者设置为_www:_www的Apache Web服务器。我永远不知道文件权限的最佳实践是什么,例如当我创建新的 Laravel 5 项目时。

Laravel 5 要求/storage文件夹是可写的。我发现了很多不同的方法来让它工作,我通常以递归地777 chmod 结束。我知道这不是最好的主意。

官方文件说:

Laravel可能需要一些权限才能配置:文件夹中的文件夹 storagevendor需要 Web 服务器的写入访问权限。

这是否意味着 Web 服务器也需要访问storagevendor文件夹本身,或者只需要访问其当前内容?

我认为更好的是更改所有者而不是权限。我将 Laravel 的所有文件权限递归更改为 _www:_www 这使网站正常工作,就好像我将 chmod 更改为 777 一样。问题是现在我的文本编辑器每次我想保存任何文件时都会要求我输入密码,如果我尝试在 Finder 中更改任何内容(例如复制文件(,也会发生同样的情况。

解决这些问题的正确方法是什么?

  1. 更改chmod
  2. 更改文件的所有者以匹配 Web服务器,也许将文本编辑器(和Finder?(设置为跳过 要求输入密码,或让他们使用sudo
  3. 更改 Web 服务器的所有者以匹配操作系统用户(我不知道后果(
  4. 别的

只是为了向任何观看此讨论的人陈述显而易见的事情......如果您授予任何文件夹 777 权限,则允许任何人读取、写入和执行该目录中的任何文件。这意味着您已授予任何人(全世界任何黑客或恶意人员(上传任何文件、病毒或任何其他文件的权限,然后执行该文件......

如果您将文件夹权限设置为 777,则您已打开服务器到可以找到该目录的任何人。 足够清晰??? :)

基本上有两种方法可以设置您的所有权和权限。要么你给自己所有权,要么你让网络服务器成为所有文件的所有者。

Web服务器作为所有者(大多数人的做法,以及Laravel文档的方式(:

假设www-data(可能是其他东西(是你的网络服务器用户。

sudo chown -R www-data:www-data/path/to/your/laravel/root/directory
如果这样做,Web服务器拥有所有文件,并且也是组,并且

您将在通过FTP上传文件或处理文件时遇到一些问题,因为您的FTP客户端将以您身份登录,而不是您的Web服务器,因此将您的用户添加到Web服务器用户组:

sudo usermod -a -G www-data ubuntu

当然,这假设你的网络服务器以www-data(Homestead默认(运行,并且你的用户是ubuntu(如果你使用Homestead,它是流浪的(。

然后,将所有目录设置为 755,将文件设置为 644...设置文件权限

sudo find/path/to/your/laravel/root/directory -type f -exec chmod 644 {} '';   

设置目录权限

sudo find/path/to/your/laravel/root/directory -type d -exec chmod 755 {} '';

您的用户作为所有者

我更喜欢拥有所有的目录和文件(它使处理一切变得更加容易(,所以,转到你的 laravel 根目录:

cd /var/www/html/laravel >> assuming this is your current root directory
sudo chown -R $USER:www-data .

然后我给自己和网络服务器权限:

sudo find . -type f -exec chmod 664 {} '';  须藤找到 .-type d -exec chmod 775 {} '';

然后授予 Web 服务器读取和写入存储和缓存的权限

无论您采用哪种方式设置它,您都需要向 Web 服务器授予读取和写入权限,以便存储、缓存和 Web 服务器也需要上传或写入的任何其他目录(取决于您的情况(,因此请运行上面的 bashy 命令:

sudo chgrp -R www-data storage bootstrap/cachesudo chmod -R ug+rwx storage bootstrap/cache

现在,您是安全的,您的网站可以正常工作,并且您可以相当轻松地处理这些文件

出于明显的安全原因,storagevendor文件夹的权限应保持在 775

但是,您的计算机和服务器 Apache 都需要能够在这些文件夹中写入。例如:当你运行像php artisan这样的命令时,你的电脑需要用storage写入日志文件。

您需要做的就是将文件夹的所有权交给 Apache :

sudo chown -R www-data:www-data /path/to/your/project/vendor
sudo chown -R www-data:www-data /path/to/your/project/storage

然后,您需要将您的用户(由其username引用(添加到服务器Apache所属的组中。这样:

sudo usermod -a -G www-data userName

注意:最常见的是组名称是www-data但在您的情况下,请将其替换为_www

我们在为 Laravel 应用程序设置权限时遇到了许多边缘情况。我们创建一个单独的用户帐户(deploy(用于拥有Laravel应用程序文件夹并从CLI执行Laravel命令,并在www-data下运行Web服务器。这导致的一个问题是日志文件可能归www-datadeploy所有,具体取决于谁首先写入日志文件,这显然会阻止其他用户将来写入它。

我发现唯一合理和安全的解决方案是使用 Linux ACL。此解决方案的目标是:

  1. 为了允许拥有/部署应用程序的用户读取和写入Laravel应用程序代码(我们使用名为deploy的用户(。
  2. 允许www-data用户读取 Laravel 应用程序代码,但不能写入访问权限。
  3. 阻止任何其他用户访问Laravel应用程序代码/数据。
  4. 允许www-data用户和应用程序用户(deploy(对存储文件夹的写入访问权限,而不管哪个用户拥有该文件(例如,deploywww-data都可以写入同一个日志文件(。

我们按如下方式完成此操作:

  1. application/文件夹中的所有文件都是使用默认掩码 0022 创建的,这会导致文件夹具有drwxr-xr-x权限,文件具有-rw-r--r--
  2. sudo chown -R deploy:deploy application/(或者简单地以deploy用户身份部署您的应用程序,这就是我们所做的(。
  3. chgrp www-data application/授予www-data组对应用程序的访问权限。
  4. chmod 750 application/允许deploy用户读/写,www-data用户只读,并删除对任何其他用户的所有权限。
  5. setfacl -Rdm u:www-data:rwx,u:deploy:rwx application/storage/设置storage/文件夹和所有子文件夹的默认权限。在存储文件夹中创建的任何新文件夹/文件都将继承这些权限(www-datadeploy rwx(。
  6. setfacl -Rm u:www-data:rwX,u:deploy:rwX application/storage/对任何现有文件/文件夹设置上述权限。
这对

我有用:

cd [..LARAVEL PROJECT ROOT]
sudo find . -type f -exec chmod 644 {} ';
sudo find . -type d -exec chmod 755 {} ';
sudo chmod -R 777 ./storage
sudo chmod -R 777 ./bootstrap/cache/

仅当你使用npm(VUE,编译SASS等(时,才添加以下内容:

sudo chmod -R 777 ./node_modules/

它的作用:

  • 将所有文件权限更改为 644
  • 将所有文件夹权限更改为 755
  • 对于存储和引导缓存(laravel用于创建和执行文件的特殊文件夹,无法从外部获得(,将权限设置为777,用于内部的任何内容
  • 对于 nodeJS 可执行文件,同上

注意:也许您不能或不需要使用 sudo 前缀执行此操作。 这取决于用户的权限、组等...

更改项目文件夹的权限,以便为组中拥有该目录的任何用户启用读/写/执行(在本例中为 _www(:

chmod -R 775 /path/to/your/project

然后将您的 OS X 用户名添加到_www组,以允许其访问该目录:

sudo dseditgroup -o edit -a yourusername -t user _www

Laravel 5.4 文档说:

安装 Laravel 后,您可能需要配置一些权限。storagebootstrap/cache目录中的目录应该可由您的网络服务器写入,否则Laravel将无法运行。如果你正在使用 Homestead 虚拟机,这些权限应已设置。

此页面上有很多答案提到使用777权限。别这样。你会把自己暴露在黑客面前。

相反,请遵循其他人有关如何设置 755(或更严格(的权限的建议。您可能需要通过在终端中运行whoami来确定您的应用程序正在运行哪个用户,然后使用 chown -R 更改某些目录的所有权。

这是对我有用的:

cd /code/laravel_project
php artisan cache:clear
php artisan config:clear
sudo service php7.4-fpm stop
sudo service nginx stop
sudo chown -R $USER:www-data storage
sudo chown -R $USER:www-data bootstrap/cache
chmod -R 775 storage
chmod -R 755 bootstrap/cache
sudo service php7.4-fpm start && sudo service nginx start

灵感来自 https://stackoverflow.com/a/45673457/470749

<小时 />

如果您没有使用sudo的权限,因为许多其他答案都需要......

您的服务器可能是共享主机,例如Cloudways。

(就我而言,我已经将我的Laravel应用程序克隆到我的第二个Cloudways服务器中,但由于storagebootstrap/cache目录的权限被搞砸了,它没有完全工作。

我需要使用:

Cloudways Platform > Server > Application Settings > Reset Permission

然后我可以在终端中运行php artisan cache:clear

大多数文件夹应该是正常的"755"和文件,"644">

Laravel要求Web服务器用户可以写一些文件夹。您可以在基于 unix 的操作系统上使用此命令。

sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache

我也遵循将用户作为所有者的方式,并且用户是www-data的成员。

我的命令顺序有点不同:

cd /var/www/html/laravel-project-root 
sudo chown -R $USER:www-data .
sudo find . -type f -exec chmod 664 {} ';   
sudo find . -type d -exec chmod 775 {} ';
sudo find . -type d -exec chmod g+s {} ';  <----- NOTE THIS
sudo chgrp -R www-data storage bootstrap/cache 
sudo chmod -R ug+rwx storage bootstrap/cache

请注意这个答案的特殊性:我是唯一一个(在这里(将组位添加到每个文件夹的人。这样,如果某人或某物创建了一个新的子文件夹,它会自动www-data为组

当我们被迫部署一些用户空间文件时,就会发生这种情况,这些文件使用 FTP 预加载,因此新的子文件夹文件夹始终由 www-data 组拥有,即使由 FTP 客户端创建

另请注意,

sudo chgrp -R www-data storage bootstrap/cache>

如果执行列表中的所有命令,则不需要。但是,如果您想修复 ftp 部署,例如,您没有执行第 2 行,那么这是必需的。

bgles 发布的解决方案在最初正确设置权限方面对我来说是正确的(我使用第二种方法(,但它对 Laravel 仍然存在潜在问题。

默认情况下,Apache 将创建具有 644 权限的文件。所以这几乎是存储中的任何内容/。因此,如果您删除存储/框架/视图的内容,然后通过 Apache 访问页面,您会发现缓存视图已创建如下:

-rw-r--r-- 1 www-data www-data 1005 Dec  6 09:40 969370d7664df9c5206b90cd7c2c79c2

如果您运行"artisan serve"并访问不同的页面,您将获得不同的权限,因为CLI PHP的行为与Apache不同:

-rw-rw-r-- 1 user     www-data 16191 Dec  6 09:48 2a1683fac0674d6f8b0b54cbc8579f8e

这本身没什么大不了的,因为你不会在生产中做任何事情。但是,如果 Apache 创建了一个随后需要由用户写入的文件,它将失败。这可以应用于使用登录用户和工匠进行部署时的缓存文件、缓存视图和日志。一个简单的例子是"artisan cache:clear",它将无法删除任何www-data:www-data 644的缓存文件。

这可以通过将工匠命令作为 www-data 运行来部分缓解,因此您将执行/编写以下所有操作:

sudo -u www-data php artisan cache:clear

或者,您将避免这样做的繁琐,并将其添加到您的.bash_aliases中:

alias art='sudo -u www-data php artisan'

这已经足够好了,并且不会以任何方式影响安全性。但是在开发机器上,运行测试和清理脚本会使这变得笨拙,除非你想设置别名来使用"sudo -u www-data"来运行phpunit以及你检查构建的其他所有内容,这可能会导致创建文件。

解决方案是遵循 bgles 建议的第二部分,并将以下内容添加到/etc/apache2/envvars 中,然后重新启动(而不是重新加载(Apache:

umask 002

这将强制 Apache 默认将文件创建为 664。这本身就可能带来安全风险。然而,在这里主要讨论的Laravel环境(Homestead,Vagrant,Ubuntu(上,Web服务器在组www-data下作为用户www-data运行。因此,如果您不任意允许用户加入 www-data 组,应该不会有额外的风险。如果有人设法突破网络服务器,他们无论如何都有www-data访问级别,所以不会丢失任何东西(尽管这不是与安全性相关的最佳态度(。因此,在生产环境中它是相对安全的,而在单用户开发计算机上,这不是问题。

最终,由于您的用户在 www-data 组中,并且包含这些文件的所有目录都是 g+s(该文件始终在父目录的组下创建(,因此用户或 www-data 创建的任何内容都将是另一个的 r/w。

这就是这里的目的。

编辑

在研究上述进一步设置权限的方法时,它看起来仍然足够好,但一些调整会有所帮助:

默认情况下,目录为 775,文件为 664,所有文件都具有刚刚安装框架的用户的所有者和组。所以假设我们从这一点开始。

cd /var/www/projectroot
sudo chmod 750 ./
sudo chgrp www-data ./

我们要做的第一件事是阻止其他人的访问,并使该组成为www-data。只有 www-data 的所有者和成员才能访问该目录。

sudo chmod 2775 bootstrap/cache
sudo chgrp -R www-data bootstrap/cache

允许Web服务器创建services.json并编译.php,如官方Laravel安装指南所建议的那样。设置组粘滞位意味着这些将由创建者拥有一组 www-data。

find storage -type d -exec sudo chmod 2775 {} ';
find storage -type f -exec sudo chmod 664 {} ';
sudo chgrp -R www-data storage

我们对存储文件夹执行相同的操作,以允许创建缓存,日志,会话和视图文件。我们使用 find 来显式设置目录和文件的目录权限。我们不需要在引导/缓存中执行此操作,因为那里(通常(没有任何子目录。

您可能需要重新应用任何可执行标志,并删除 vendor/* 并重新安装作曲家依赖项以重新创建 phpunit 等的链接,例如:

chmod +x .git/hooks/*
rm vendor/*
composer install -o

就是这样。除了上面解释的 Apache 掩码之外,这是所有需要的,而无需使整个项目根可由 www-data 写入,这是其他解决方案发生的情况。因此,这种方式稍微安全一些,因为以 www-data 运行的入侵者具有更有限的写入访问权限。

结束编辑

系统版的更改

这适用于 php-fpm 的使用,但也许也适用于其他用途。

需要覆盖标准 systemd 服务,在 override.conf 文件中设置掩码,然后重新启动服务:

sudo systemctl edit php7.0-fpm.service
Use:
    [Service]
    UMask=0002
Then:
sudo systemctl daemon-reload
sudo systemctl restart php7.0-fpm.service

添加到作曲家.json

"scripts": {
    "post-install-cmd": [
      "chgrp -R www-data storage bootstrap/cache",
      "chmod -R ug+rwx storage bootstrap/cache"
    ]
}

composer install

如已经发布的那样

您需要做的就是将文件夹的所有权交给 Apache :

但我为 chown 命令添加了 -R sudo chown -R www-data:www-data /path/to/your/project/vendor sudo chown -R www-data:www-data /path/to/your/project/storage

我已经在EC2实例上安装了laravel,并花了3天时间修复权限错误,并最终修复了它。所以我想和其他人分享这个经验。

  1. 用户问题当我登录 ec2 实例时,我的用户名是 ec2-user,用户组是 ec2-user。该网站在httpd用户:apache:apache下工作所以我们应该为 Apache 设置权限。

  2. 文件夹和文件权限一个。 文件夹结构首先,您应该确保在存储下具有这样的文件夹结构

    存储

    • 框架
      • 缓存
      • 会话
      • 视图
    • 原木文件夹结构可以根据您使用的 laravel 版本而有所不同。我的Laravel版本是5.2,您可以根据您的版本找到合适的结构。

B. 许可 首先,我看到在存储下设置777以删除file_put_contents的说明:无法打开流错误。 所以我设置了存储权限 777 CHMOD -R 777 存储 但是错误没有修复。 在这里,您应该考虑一个:谁将文件写入存储/会话和视图。 这不是ec2用户,而是apache。 是的,对。 "Apache"用户将文件(会话文件,编译的视图文件(写入会话和视图文件夹。 因此,您应该授予 apache 对这些文件夹的写入权限。 默认情况下:SELinux 表示/var/www 文件夹应该由 apache deamon 只读。

因此,为此,我们可以将 selinux 设置为 0: 设置强制 0

这可以暂时解决问题,但这会使 mysql 不起作用。 所以这不是一个好的解决方案。

您可以使用以下命令为存储文件夹设置读写上下文:(请记住设置强制 1 进行测试(

chcon -Rt httpd_sys_content_rw_t storage/

然后您的问题将得到解决。

  1. 不要忘记这一点作曲家更新PHP 工匠缓存:清除

    这些命令在之后或之前都很有用。

    我希望你节省你的时间。祝你好运。哈肯

我已经使用这个片段超过 3 年了。


laravel new demo 
cd demo 
sudo find ./ -type f -exec chmod 664 {} ';    
sudo find ./  -type d -exec chmod 775 {} ';
sudo chgrp -Rf www-data storage bootstrap/cache
sudo chmod -Rf ug+rwx storage bootstrap/cache
sudo chmod -Rf 775 storage/ bootstrap/
php artisan storage:link

@realtebo建议看起来不错。我将尝试。

sudo find . -type d -exec chmod g+s {} ';  <----- NOTE THIS

我们将授予 755 存储权限和引导文件夹权限

sudo chmod -R 755 bootstrap/cache
sudo chmod -R 755 storage

解决方案 2我们将所有文件和文件夹所有权交给网络服务器用户

sudo chown -R www-data:www-data /var/www/your-project-path

为所有文件设置 644 权限,为所有目录设置 755 权限。

sudo find /var/www/your-project-path -type f -exec chmod 644 {} '; 
sudo find /var/www/your-project-path -type d -exec chmod 755 {} '; 

我们将为文件和文件夹提供适当的读写权限。

cd /var/www/your-project-path
sudo chgrp -R www-data storage bootstrap/cache 
sudo chmod -R ug+rwx storage bootstrap/cache 

最重要的是 Ubuntu 服务器的所有细节

这是在 2017 年为 5.1~5.2 版本编写的。在更高版本的 Laravel 上使用它之前,请使用一些常识。

我决定编写自己的脚本来减轻设置项目的一些痛苦。

在项目根目录中运行以下命令:

wget -qO- https://raw.githubusercontent.com/defaye/bootstrap-laravel/master/bootstrap.sh | sh

等待引导完成,一切顺利。

使用前查看脚本。

我有以下配置:

  • NGINX (运行用户: nginx (
  • PHP-FPM

并按照接受的答案中的建议正确应用了权限@bgies。在我的情况下,问题是php-fpm配置的正在运行的用户和组,该用户和组最初是apache的。

如果你将NGINX与php-fpm一起使用,你应该打开php-fpm的配置文件:

nano /etc/php-fpm.d/www.config

并将usergroup选项的值替换为一个 NGINX 配置为使用的选项;在我的情况下,两者都nginx

... ; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. ; RPM: apache Choosed to be able to access some dir as httpd user = nginx ; RPM: Keep a group allowed to write in log dir. group = nginx ...

保存它并重新启动nginx和php-fpm服务。

对于Laravel开发人员来说,目录问题可能有点痛苦。在我的应用程序中,我正在动态创建目录,并在本地环境中成功地将文件移动到此目录。然后在服务器上,我在将文件移动到新创建的目录时遇到错误。

以下是我所做的事情,并在最后取得了成功的结果。


  1. sudo find /path/to/your/laravel/root/directory -type f -exec chmod 664 {} '; sudo find /path/to/your/laravel/root/directory -type d -exec chmod 775 {} ';
  2. chcon -Rt httpd_sys_content_rw_t /path/to/my/file/upload/directory/in/laravel/project/
  3. 在动态创建新目录时,我使用了命令mkdir($save_path, 0755, true);

在生产服务器上进行这些更改后,我成功地创建了新目录并将文件移动到其中。

最后,如果你在Laravel中使用文件外观,你可以做这样的事情: File::makeDirectory($save_path, 0755, true);

我会这样做:

sudo chown -R $USER:www-data laravel-project/ 
find laravel-project/ -type f -exec chmod 664 {} ';
find laravel-project/ -type d -exec chmod 775 {} ';

最后,您需要授予 Web 服务器修改storagebootstrap/cache目录的权限:

sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache

如果某些文件中有一些代码更改,然后又更改了一些权限,则设置正确的权限并再次提交可能比尝试选择具有权限更改的文件更容易。您只剩下代码更改。

我找到了更好的解决方案。这是因为 php 默认以其他用户身份运行。

所以要解决这个问题,请

sudo nano /etc/php/7.0/fpm/pool.d/www.conf

然后编辑 user = "put user that owns the directories" group = "put user that owns the directories"

然后:

sudo systemctl reload php7.0-fpm

sudo chown -R $USER:www-data your_directory_name_under_storage_app

它将向服务器用户和服务器提供文件访问所需的权限。

Mac OS Big Sur

  1. 就我而言,
    工匠无法访问 /var/www/{project_name}/storage
    /logs 文件夹中创建文件所以我不得不手动去 /var并创建Laravel制作符号链接所需的文件夹结构。

  2. 添加对文件夹的访问权限 sudo chgrp -R $USER /var/www/project_name

  3. 然后我可以使用 php artisan storage:link没有任何问题。