Laravel 存储 SFTP 和上传文件权限
Laravel Storage SFTP and uploaded files permissions
我正在使用 Storage:SFTP (league/flysystem-sftp) 将一些文件上传到外部服务器。一切顺利,但有一个小问题:文件是使用 0644 (-rw-r--r--) 权限上传的。我尝试在 put 方法上使用 'public' 选项作为文档中的示例,例如
Storage::disk('remote-sftp')->put($filename, $contents, 'public');
但如果失败返回 FALSE 并且不上传文件。
如果我删除 'public' 参数,一切正常,但文件权限错误。
有什么方法可以将上传文件的权限设置为0666之类的吗?
请试试这个:
Storage::disk('remote-sftp')->put($filename, $contents)->setVisibility( $filename, 'public');
假设文件名也有路径..
最终解决方案是结合Alpy的答案和配置。
调用 setVisibility() 没有失败,但在 0644 中保留权限。深入研究 FTP/SFTP 驱动程序发现 'public' 权限有一个模式,可以使用 'permPublic' 键在配置中分配,所以在 config/filesystems.php 中写入所需的八进制权限,它按预期工作。
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'remote-sftp' => [
'driver' => 'sftp',
'host' => '222.222.222.222',
'username' => 'myuser',
'password' => 'mypassword',
'visibility' => 'public',
'permPublic' => 0766, /// <- this one did the trick
// 'port' => 22,
'root' => '/home',
// 'timeout' => 30,
],
],
];
文件权限基于两个因素。可见性和权限。您可以在驱动程序配置中设置这两个选项:
'remote' => [
'driver' => 'sftp',
'host' => 'hostname',
'root' => '/',
'username' => 'user',
'password' => env('SYSTEM_PASS'),
'visibility' => 'public', // defaults to 'private'
'permPublic' => 0775
]
权限是根据可见性设置的。因此,如果您设置 'permPublic'
而未设置 'visibility'
,则不会发生任何变化,因为 setVisibility()
函数使用 'visibility'
来获取权限。
vendor/league/flysystem-sftp/src/SftpAdapter.php
public function setVisibility($path, $visibility)
{
$visibility = ucfirst($visibility);
// We're looking for either permPublic or permPrivate
if (! isset($this->{'perm'.$visibility})) {
throw new InvalidArgumentException('Unknown visibility: '.$visibility);
}
$connection = $this->getConnection();
return $connection->chmod($this->{'perm'.$visibility}, $path);
}
public默认为0755
。
私有默认为0700
。
umask
如果未设置'visibility'
,我相信权限是根据远程系统用户的umask 设置的。如果您愿意,您可以在远程系统上修改它。 set umask for user
目录
使用权限时要注意的一件事是,这只会影响创建的 文件。要设置创建目录的权限,请在配置中使用 'directoryPerm'
属性。
这默认为 0744
存储::磁盘('sftp')->下载(...
这是一个更加全局和高效的解决方案。在递归目录下保存文件时,我需要控制文件和目录的权限。
League SftpAdapter 正在递归创建目录(如果目录尚不存在)。但主要问题是,它不会为目录添加 permPublic => 0755
,而只会为文件添加,因此 www-data
如果文件位于新创建的目录中,用户最终将无法访问该文件。解决方案是深入代码以查看发生了什么:
'disks' => [
'remote-sftp' => [
'driver' => 'sftp',
'host' => '222.222.222.222',
'port' => 22,
'username' => 'user',
'password' => 'password',
'visibility' => 'public', // set to public to use permPublic, or private to use permPrivate
'permPublic' => 0755, // whatever you want the public permission is, avoid 0777
'root' => '/path/to/web/directory',
'timeout' => 30,
'directoryPerm' => 0755, // whatever you want
],
],
在League\Flysystem\Sftp\StfpAdapter
中,有2个重要的属性可以看清楚:
/**
* @var array
*/
protected $configurable = ['host', 'hostFingerprint', 'port', 'username', 'password', 'useAgent', 'agent', 'timeout', 'root', 'privateKey', 'passphrase', 'permPrivate', 'permPublic', 'directoryPerm', 'NetSftpConnection'];
/**
* @var int
*/
protected $directoryPerm = 0744;
$configurable
是配置文件系统 sftp 驱动程序的所有可能键。您可以在配置文件中将 directoryPerm
从 0744
更改为 0755
:
'directoryPerm' => 0755,
但是,因为 StfpAdapter https://github.com/thephpleague/flysystem-sftp/issues/81 中有一个 Bug,它不会在 createDir
:
上使用 $config 参数
$filesystem = Storage::disk('remote-sftp');
$filesystem->getDriver()->getAdapter()->setDirectoryPerm(0755);
$filesystem->put('dir1/dir2/'.$filename, $contents);
或者故意设置成public:
$filesystem->put('dir1/dir2/'.$filename, $contents, 'public');
我在寻找解决方案时发现了这个问题,我想我在深入研究 flysystem 代码后找到了 Laravel 9 中有效的方法。
将以下设置添加到我的配置中看起来已经成功了。
'visibility' => 'public',
'permissions' => [
'file' => [
'public' => 0664,
'private' => 0664,
],
'dir' => [
'public' => 0775,
'private' => 0775,
],
],
我正在使用 Storage:SFTP (league/flysystem-sftp) 将一些文件上传到外部服务器。一切顺利,但有一个小问题:文件是使用 0644 (-rw-r--r--) 权限上传的。我尝试在 put 方法上使用 'public' 选项作为文档中的示例,例如
Storage::disk('remote-sftp')->put($filename, $contents, 'public');
但如果失败返回 FALSE 并且不上传文件。
如果我删除 'public' 参数,一切正常,但文件权限错误。
有什么方法可以将上传文件的权限设置为0666之类的吗?
请试试这个:
Storage::disk('remote-sftp')->put($filename, $contents)->setVisibility( $filename, 'public');
假设文件名也有路径..
最终解决方案是结合Alpy的答案和配置。 调用 setVisibility() 没有失败,但在 0644 中保留权限。深入研究 FTP/SFTP 驱动程序发现 'public' 权限有一个模式,可以使用 'permPublic' 键在配置中分配,所以在 config/filesystems.php 中写入所需的八进制权限,它按预期工作。
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'remote-sftp' => [
'driver' => 'sftp',
'host' => '222.222.222.222',
'username' => 'myuser',
'password' => 'mypassword',
'visibility' => 'public',
'permPublic' => 0766, /// <- this one did the trick
// 'port' => 22,
'root' => '/home',
// 'timeout' => 30,
],
],
];
文件权限基于两个因素。可见性和权限。您可以在驱动程序配置中设置这两个选项:
'remote' => [
'driver' => 'sftp',
'host' => 'hostname',
'root' => '/',
'username' => 'user',
'password' => env('SYSTEM_PASS'),
'visibility' => 'public', // defaults to 'private'
'permPublic' => 0775
]
权限是根据可见性设置的。因此,如果您设置 'permPublic'
而未设置 'visibility'
,则不会发生任何变化,因为 setVisibility()
函数使用 'visibility'
来获取权限。
vendor/league/flysystem-sftp/src/SftpAdapter.php
public function setVisibility($path, $visibility)
{
$visibility = ucfirst($visibility);
// We're looking for either permPublic or permPrivate
if (! isset($this->{'perm'.$visibility})) {
throw new InvalidArgumentException('Unknown visibility: '.$visibility);
}
$connection = $this->getConnection();
return $connection->chmod($this->{'perm'.$visibility}, $path);
}
public默认为0755
。
私有默认为0700
。
umask
如果未设置'visibility'
,我相信权限是根据远程系统用户的umask 设置的。如果您愿意,您可以在远程系统上修改它。 set umask for user
目录
使用权限时要注意的一件事是,这只会影响创建的 文件。要设置创建目录的权限,请在配置中使用 'directoryPerm'
属性。
这默认为 0744
存储::磁盘('sftp')->下载(...
这是一个更加全局和高效的解决方案。在递归目录下保存文件时,我需要控制文件和目录的权限。
League SftpAdapter 正在递归创建目录(如果目录尚不存在)。但主要问题是,它不会为目录添加 permPublic => 0755
,而只会为文件添加,因此 www-data
如果文件位于新创建的目录中,用户最终将无法访问该文件。解决方案是深入代码以查看发生了什么:
'disks' => [
'remote-sftp' => [
'driver' => 'sftp',
'host' => '222.222.222.222',
'port' => 22,
'username' => 'user',
'password' => 'password',
'visibility' => 'public', // set to public to use permPublic, or private to use permPrivate
'permPublic' => 0755, // whatever you want the public permission is, avoid 0777
'root' => '/path/to/web/directory',
'timeout' => 30,
'directoryPerm' => 0755, // whatever you want
],
],
在League\Flysystem\Sftp\StfpAdapter
中,有2个重要的属性可以看清楚:
/**
* @var array
*/
protected $configurable = ['host', 'hostFingerprint', 'port', 'username', 'password', 'useAgent', 'agent', 'timeout', 'root', 'privateKey', 'passphrase', 'permPrivate', 'permPublic', 'directoryPerm', 'NetSftpConnection'];
/**
* @var int
*/
protected $directoryPerm = 0744;
$configurable
是配置文件系统 sftp 驱动程序的所有可能键。您可以在配置文件中将 directoryPerm
从 0744
更改为 0755
:
'directoryPerm' => 0755,
但是,因为 StfpAdapter https://github.com/thephpleague/flysystem-sftp/issues/81 中有一个 Bug,它不会在 createDir
:
$filesystem = Storage::disk('remote-sftp');
$filesystem->getDriver()->getAdapter()->setDirectoryPerm(0755);
$filesystem->put('dir1/dir2/'.$filename, $contents);
或者故意设置成public:
$filesystem->put('dir1/dir2/'.$filename, $contents, 'public');
我在寻找解决方案时发现了这个问题,我想我在深入研究 flysystem 代码后找到了 Laravel 9 中有效的方法。
将以下设置添加到我的配置中看起来已经成功了。
'visibility' => 'public',
'permissions' => [
'file' => [
'public' => 0664,
'private' => 0664,
],
'dir' => [
'public' => 0775,
'private' => 0775,
],
],