You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现WordPress已登录获批用户安全下载GCS桶内文件?

解决方案:WordPress 集成 GCS 实现安全同步下载

核心思路

通过 WordPress 登录验证 + GCS 签名 URL + 自动文件同步 + 细粒度权限控制,解决你的需求:

  • 仅登录且有权限的用户可下载
  • 上传到 GCS 的文件自动同步到站点
  • 支持按文件夹/文件分配用户权限

1. 准备 GCS 服务账号与权限

  • 登录 Google Cloud 控制台,创建一个服务账号,为其分配 Storage Object Viewer 权限(遵循最小权限原则,仅允许查看和生成文件签名)
  • 下载服务账号的 JSON 密钥文件,上传到 WordPress 站点的安全目录(比如主题的 private 文件夹,确保不对外公开访问)

2. 集成 Google Cloud PHP 客户端库

在 WordPress 主题或自定义插件中,使用 Composer 安装官方客户端库:

composer require google/cloud-storage

若主机不支持 Composer,可手动下载库文件并引入到项目中。

3. 自动同步 GCS 文件到 WordPress

创建自定义文章类型(gcs_file)存储 GCS 文件元数据,通过 WP Cron 定时完成同步:

3.1 注册自定义文章类型

在主题的 functions.php 或自定义插件中添加:

function register_gcs_file_cpt() {
    $args = [
        'label' => 'GCS 文件',
        'public' => true,
        'show_ui' => true,
        'capabilities' => [
            'edit_post' => 'manage_options', // 仅管理员可编辑
            'read_post' => 'read', // 登录用户可查看
        ],
        'supports' => ['title'],
        'rewrite' => false,
    ];
    register_post_type('gcs_file', $args);
}
add_action('init', 'register_gcs_file_cpt');

3.2 编写同步函数

function sync_gcs_files() {
    // 加载客户端库
    require_once get_template_directory() . '/vendor/autoload.php';

    // 初始化 GCS 客户端
    $storage = new Google\Cloud\Storage\StorageClient([
        'keyFilePath' => get_template_directory() . '/private/gcs-service-account.json',
        'projectId' => '你的GCP项目ID',
    ]);
    $bucket = $storage->bucket('你的GCS存储桶名称');

    // 遍历桶内所有文件
    foreach ($bucket->objects(['prefix' => '', 'delimiter' => '/']) as $object) {
        $file_path = $object->name();
        // 跳过 GCS 中的虚拟文件夹(以/结尾的前缀)
        if (substr($file_path, -1) === '/') continue;

        // 检查文件是否已同步到 WordPress
        $existing_post = get_posts([
            'post_type' => 'gcs_file',
            'meta_key' => 'gcs_file_path',
            'meta_value' => $file_path,
            'posts_per_page' => 1,
        ]);

        if (empty($existing_post)) {
            // 创建新的文章记录
            $post_id = wp_insert_post([
                'post_title' => basename($file_path),
                'post_type' => 'gcs_file',
                'post_status' => 'publish',
            ]);
            // 存储文件元数据
            update_post_meta($post_id, 'gcs_file_path', $file_path);
            update_post_meta($post_id, 'gcs_file_size', $object->size());
            // 提取父文件夹,用于后续权限控制
            $parent_folder = dirname($file_path);
            update_post_meta($post_id, 'gcs_parent_folder', $parent_folder);
        }
    }
}

3.3 设置定时任务

添加每日同步的定时任务:

function setup_gcs_sync_cron() {
    if (!wp_next_scheduled('gcs_sync_event')) {
        wp_schedule_event(time(), 'daily', 'gcs_sync_event');
    }
}
add_action('wp', 'setup_gcs_sync_cron');
add_action('gcs_sync_event', 'sync_gcs_files');

4. 生成安全的签名下载链接

创建自定义短代码,在登录后页面显示文件列表,并生成带权限验证的下载链接:

4.1 短代码函数

function gcs_file_list_shortcode() {
    if (!is_user_logged_in()) return '请先登录';

    $files = get_posts([
        'post_type' => 'gcs_file',
        'posts_per_page' => -1,
        'orderby' => 'title',
        'order' => 'ASC',
    ]);

    $output = '<ul class="gcs-file-list">';
    foreach ($files as $file) {
        $file_path = get_post_meta($file->ID, 'gcs_file_path', true);
        // 生成指向自定义下载端点的链接
        $download_url = add_query_arg(['gcs_download' => $file_path], home_url());
        $file_size = size_format(get_post_meta($file->ID, 'gcs_file_size', true));
        $output .= sprintf(
            '<li><a href="%s" class="gcs-download-link">%s</a> <span class="file-size">(%s)</span></li>',
            esc_url($download_url),
            esc_html($file->post_title),
            esc_html($file_size)
        );
    }
    $output .= '</ul>';
    return $output;
}
add_shortcode('gcs_file_list', 'gcs_file_list_shortcode');

4.2 处理下载请求

在 functions.php 中添加请求处理逻辑,验证权限并生成签名 URL:

function handle_gcs_download() {
    if (!isset($_GET['gcs_download']) || !is_user_logged_in()) {
        wp_redirect(home_url());
        exit;
    }

    $file_path = sanitize_text_field($_GET['gcs_download']);
    $current_user = wp_get_current_user();

    // 1. 验证文件存在性
    $post = get_posts([
        'post_type' => 'gcs_file',
        'meta_key' => 'gcs_file_path',
        'meta_value' => $file_path,
        'posts_per_page' => 1,
    ])[0] ?? null;
    if (!$post) {
        wp_die('文件不存在');
    }

    // 2. 检查用户权限(示例:按文件夹映射角色)
    $parent_folder = get_post_meta($post->ID, 'gcs_parent_folder', true);
    // 示例:若文件在/sales/文件夹下,仅允许sales角色用户下载
    if ($parent_folder === 'sales' && !in_array('sales', $current_user->roles)) {
        wp_die('你没有权限下载该文件');
    }

    // 3. 生成 GCS 签名 URL(有效期5分钟)
    require_once get_template_directory() . '/vendor/autoload.php';
    $storage = new Google\Cloud\Storage\StorageClient([
        'keyFilePath' => get_template_directory() . '/private/gcs-service-account.json',
        'projectId' => '你的GCP项目ID',
    ]);
    $bucket = $storage->bucket('你的GCS存储桶名称');
    $object = $bucket->object($file_path);
    $signed_url = $object->signedUrl(
        new DateTime('+5 minutes'),
        [
            'version' => 'v4',
        ]
    );

    // 4. 重定向到签名 URL
    wp_redirect($signed_url);
    exit;
}
add_action('template_redirect', 'handle_gcs_download');

5. 细粒度权限控制扩展

  • 在自定义文章类型的编辑页面添加自定义字段,手动指定允许下载的用户角色或用户ID
  • 根据 GCS 文件夹命名规则自动映射权限(比如文件夹名对应 WordPress 角色名)
  • 针对单个文件,可在同步时添加额外元数据,关联特定用户

内容的提问来源于stack exchange,提问作者Dylan Russell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:35:25