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

WordPress自定义REST API endpoint:文件上传与安全验证及字段存储咨询

实现WordPress自定义REST API的文件上传与安全验证

一、添加Nonce验证防范CSRF攻击

WordPress REST API默认支持通过X-WP-Nonce头验证请求合法性,步骤如下:

  1. 前端获取Nonce
    在插件的PHP代码中,通过本地化脚本将nonce传递给Vue应用:
wp_localize_script( 'your-vue-app-script', 'wpApiData', array(
    'restRoot' => esc_url_raw( rest_url() ),
    'nonce' => wp_create_nonce( 'wp_rest' )
) );

Vue中直接通过window.wpApiData.nonce即可获取该值。

  1. 前端请求携带Nonce
    使用FormData上传文件时,将nonce放入请求头:
const formData = new FormData();
// 添加多个文件
formData.append('required_file_1', fileInput1.files[0]);
formData.append('required_file_2', fileInput2.files[0]);

// 发起请求
axios.post(`${window.wpApiData.restRoot}your-plugin/v1/user-register`, formData, {
    headers: {
        'X-WP-Nonce': window.wpApiData.nonce,
        'Content-Type': 'multipart/form-data'
    }
});
  1. 后端验证Nonce
    注册endpoint时,通过permission_callback统一验证nonce,不通过则直接返回403:
add_action( 'rest_api_init', function() {
    register_rest_route( 'your-plugin/v1', '/user-register', array(
        'methods' => WP_REST_Server::CREATABLE,
        'callback' => 'handle_user_reg_with_upload',
        'permission_callback' => function() {
            return isset($_SERVER['HTTP_X_WP_NONCE']) && wp_verify_nonce($_SERVER['HTTP_X_WP_NONCE'], 'wp_rest');
        }
    ) );
} );

二、处理多个必填文件上传

在后端回调函数中,先校验文件是否存在,再用WordPress内置函数处理上传:

function handle_user_reg_with_upload( $request ) {
    // 定义必填文件字段名
    $required_files = ['required_file_1', 'required_file_2'];
    $missing = [];
    $uploaded_urls = [];

    // 检查必填文件是否上传成功
    foreach($required_files as $file_key) {
        if( !isset($_FILES[$file_key]) || $_FILES[$file_key]['error'] !== UPLOAD_ERR_OK ) {
            $missing[] = $file_key;
        }
    }
    if( !empty($missing) ) {
        return new WP_Error( 'missing_files', '必填文件缺失:' . implode(', ', $missing), ['status' => 400] );
    }

    // 处理每个文件上传
    foreach($required_files as $file_key) {
        $file = $_FILES[$file_key];
        // 限制文件类型(示例:仅允许图片和PDF)
        $allowed_mimes = ['image/jpeg', 'image/png', 'application/pdf'];
        if( !in_array($file['type'], $allowed_mimes) ) {
            return new WP_Error( 'invalid_type', "{$file_key} 文件类型不允许", ['status' => 400] );
        }
        // 限制文件大小(示例:5MB)
        $max_size = 5 * 1024 * 1024;
        if( $file['size'] > $max_size ) {
            return new WP_Error( 'too_large', "{$file_key} 文件超过5MB限制", ['status' => 400] );
        }

        // 使用WordPress内置函数处理上传
        $upload_overrides = ['test_form' => false];
        $upload_result = wp_handle_upload( $file, $upload_overrides );
        
        if( $upload_result && !isset($upload_result['error']) ) {
            $uploaded_urls[$file_key] = $upload_result['url'];
        } else {
            return new WP_Error( 'upload_fail', "{$file_key} 上传失败:{$upload_result['error']}", ['status' => 500] );
        }
    }

    // 后续用户注册逻辑...
}

三、将文件链接存入用户Meta字段

完成文件上传和用户注册后,直接用update_user_meta存储链接:

// 假设已完成用户注册,$user_id为新用户ID
$user_id = wp_create_user( $username, $password, $email );
if( is_wp_error($user_id) ) {
    // 注册失败时清理已上传文件
    foreach($uploaded_urls as $url) {
        $file_path = str_replace( site_url('/'), ABSPATH, $url );
        if( file_exists($file_path) ) unlink($file_path);
    }
    return $user_id;
}

// 存储单个文件链接
update_user_meta( $user_id, 'user_resume', $uploaded_urls['required_file_1'] );
// 存储多个文件链接(自动序列化数组)
update_user_meta( $user_id, 'user_uploaded_docs', $uploaded_urls );

后续可通过get_user_meta( $user_id, 'user_uploaded_docs', true )获取完整的文件链接数组。

额外注意事项

  • 若用户注册失败,务必清理已上传的文件,避免服务器空间浪费;
  • 可通过add_filter('upload_mimes')全局限制站点允许的上传文件类型,替代回调内的单独校验;
  • 生产环境建议开启HTTPS,防止nonce被窃取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:55:29