WordPress自定义REST API endpoint:文件上传与安全验证及字段存储咨询
实现WordPress自定义REST API的文件上传与安全验证
一、添加Nonce验证防范CSRF攻击
WordPress REST API默认支持通过X-WP-Nonce头验证请求合法性,步骤如下:
- 前端获取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即可获取该值。
- 前端请求携带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' } });
- 后端验证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
相关产品推荐
相关产品推荐

