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 驱动程序的所有可能键。您可以在配置文件中将 directoryPerm0744 更改为 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,
     ],
],