我目前正在开发一种表单,允许用户更新特定的订单详细信息,包括费用和费用原因。成功更新订单后,表单会显示 JavaScript 警报,并且更新的数据会反映在订单的元数据中。但是,我遇到了用户所有权验证问题。
这是我面临的问题:
所有权验证:我想确保用户只能更新与其用户 ID 关联的订单,而不能更新属于其他人的订单。目前,当用户输入与其帐户不关联的订单 ID 时,订单元数据不会更新,但仍会触发成功更新的 JavaScript 警报。
我在下面添加了我的代码以供参考:
<form id="expense_form" class="expense_form" action="" method="post">
<label for="order-id">Order ID:</label>
<input class="exp_order_no" id="exp_order_no" type="text" pattern="[0-9]*" placeholder="Enter the Order Number" required>
<label for="expense">Expense:</label>
<input class="expense_amt" id="expense_amt" type="text" pattern="[0-9]*" placeholder="Enter the expense amount" required>
<label for="reason">Reason for Expense:</label>
<textarea class="expense_reason" id="expense_reason" id="reason" name="reason" rows="4" placeholder="Enter Message" required></textarea>
<input type="submit" class="exp_but" id="exp_but" value="Submit">
</form>
<script>
jQuery(document).ready(function($) {
$('#expense_form').on('submit', function(e) {
e.preventDefault();
var orderid = $('#exp_order_no').val();
var expense = $('#expense_amt').val();
var expense_reason = $('#expense_reason').val();
// console.log (orderid);
// console.log (expense);
// console.log (expense_reason);
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action:'update_custom_field_order_expense_php',
orderid: orderid,
expense: expense,
expense_reason:expense_reason
},
success: function( response ) {
console.log( 'Custom field updated successfully.' );
alert('Expense Submitted Successfully !!');
location.reload();
},
error: function( response ) {
console.log( 'Failed to Submit Expense.' );
alert('Expense Not Submitted !! Please enter correct order id.');
location.reload();
}
});
});
});
</script>
<?php
add_action( 'wp_ajax_update_custom_field_order_expense_php', 'update_custom_field_order_expense_php' );
add_action('wp_ajax_nopriv_update_custom_field_order_expense_php', 'update_custom_field_order_expense_php');
function update_custom_field_order_expense_php() {
$order_id = $_POST['orderid'];
$order_expense = $_POST['expense'];
$order_expense_reason = $_POST['expense_reason'];
$order = wc_get_order( $order_id );
if ( is_user_logged_in()) {
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
$driver_id = get_post_meta($order_id, 'lddfw_driverid', true);
//$current_date = date_i18n( 'j F, Y', strtotime( $current_date_time ) );
if($current_user_id == $driver_id ){
$order->update_meta_data( 'Driver Expense', $order_expense );
$order->update_meta_data( 'Driver Expense Reason',$order_expense_reason);
$order->save();
wp_send_json_success();
exit;
}else{
wp_send_json_error();
exit;
}
}
}
?>
尝试以下重新访问和增强的代码版本,检查当前用户 ID 与为请求的订单 ID 注册的驱动程序 ID 是否匹配。
我添加了一个隐藏的用户 ID 输入字段和一个隐藏的消息框,其中显示处理消息。
形式:
<?php if ( is_user_logged_in()) : ?>
<form id="expense_form" class="expense_form" action="" method="post">
<label for="order-id"><?php _e('Order ID'); ?>:</label>
<input class="exp_order_no" id="exp_order_no" type="text" pattern="[0-9]*" placeholder="Enter the Order Number" required>
<label for="expense"><?php _e('Expense'); ?>:</label>
<input class="expense_amt" id="expense_amt" type="text" pattern="[0-9]*" placeholder="Enter the expense amount" required>
<label for="reason"><?php _e('Reason for Expense'); ?>:</label>
<textarea class="expense_reason" id="expense_reason" id="reason" name="reason" rows="4" placeholder="<?php _e('Enter Message'); ?>" required></textarea>
<p id="message-response" style="display:none;"></p>
<input type="submit" class="exp_but" id="exp_but" value="<?php _e('Submit'); ?>">
<input type="hidden" id="user_id" name="user_id" value="<?php echo get_current_user_id(); ?>">
</form>
<?php endif; ?>
jQuery 代码
jQuery(function($) {
$('#expense_form').on('submit', function(e) {
e.preventDefault();
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'add_order_expense_cf',
order_id: $('#exp_order_no').val(),
user_id: $('#user_id').val(),
expense: $('#expense_amt').val(),
reason: $('#expense_reason').val()
},
success: function( response ) {
const color = response.success ? 'green' : 'red',
message = response.data;
$('#message-response').html(response.data).css('color',color).fadeIn().delay(2000).fadeOut();
console.log(response);
},
error: function( error ) {
$('#message-response').html('Something went wrong, try later please.').css('color','red').fadeIn().delay(2000).fadeOut();
console.log(error);
}
});
});
});
PHP:
add_action( 'wp_ajax_add_order_expense_cf', 'add_order_expense_custom_fields' );
add_action('wp_ajax_nopriv_add_order_expense_cf', 'add_order_expense_custom_fields');
function add_order_expense_custom_fields() {
if( isset($_POST['order_id']) && isset($_POST['user_id']) ) {
$order = wc_get_order( intval($_POST['order_id']) );
if( ! is_a($order, 'WC_Order') ) {
wp_send_json_error( __('Wrong order number, please retry.') );
}
$driver_id = (int) $order->get_meta('lddfw_driverid');
if( $driver_id === 0 || intval($_POST['user_id']) !== $driver_id ) {
wp_send_json_error( __('Sorry you are not allowed to request expenses on that order number.') );
}
$order->update_meta_data( 'Driver Expense', floatval($_POST['expense']) );
$order->update_meta_data( 'Driver Expense Reason', sanitize_textarea_field($_POST['reason']) );
$order->save();
wp_send_json_success( __('Data has been successfully sent and saved.') );
}
wp_send_json_error( __('Something went wrong, please try later.') );
}
已测试且有效。