Customizer: Refresh nonces when a session expires and the user logs in again.

This was broken since 4.0 and the introduction of user session tokens. The nonces are now tied to session tokens as opposed to user IDs, and thus they change with each re-login.
Custom nonces can be added through the `customize_refresh_nonces` filter. On a successful refresh request the JavaScript API will trigger a `nonce-refresh` event. See widget's update nonce as an example.

props westonruter for initial patch.
fixes #31294.
Built from https://develop.svn.wordpress.org/trunk@32054


git-svn-id: http://core.svn.wordpress.org/trunk@32033 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Dominik Schilling 2015-04-06 15:10:27 +00:00
parent dd5b92a2fe
commit 6d2c70aa0d
7 changed files with 101 additions and 12 deletions

View File

@ -2358,11 +2358,23 @@
messenger.targetWindow( iframe[0].contentWindow );
messenger.bind( 'login', function() {
iframe.remove();
messenger.destroy();
delete previewer._login;
deferred.resolve();
messenger.bind( 'login', function () {
var refreshNonces = previewer.refreshNonces();
refreshNonces.always( function() {
iframe.remove();
messenger.destroy();
delete previewer._login;
});
refreshNonces.done( function() {
deferred.resolve();
});
refreshNonces.fail( function() {
previewer.cheatin();
deferred.reject();
});
});
return this._login;
@ -2370,6 +2382,28 @@
cheatin: function() {
$( document.body ).empty().addClass('cheatin').append( '<p>' + api.l10n.cheatin + '</p>' );
},
refreshNonces: function() {
var request, deferred = $.Deferred();
deferred.promise();
request = wp.ajax.post( 'customize_refresh_nonces', {
wp_customize: 'on',
theme: api.settings.theme.stylesheet
});
request.done( function( response ) {
api.trigger( 'nonce-refresh', response );
deferred.resolve();
});
request.fail( function() {
deferred.reject();
});
return deferred;
}
});
@ -2538,6 +2572,12 @@
$.extend( this.nonce, nonce );
});
// Refresh the nonces if login sends updated nonces over.
api.bind( 'nonce-refresh', function( nonce ) {
$.extend( api.settings.nonce, nonce );
$.extend( api.previewer.nonce, nonce );
});
// Create Settings
$.each( api.settings.settings, function( id, data ) {
api.create( id, id, data.value, {

File diff suppressed because one or more lines are too long

View File

@ -1898,6 +1898,11 @@
sidebar_widgets: api.Widgets.SidebarControl
});
// Refresh the nonce if login sends updated nonces over.
api.bind( 'nonce-refresh', function( nonces ) {
api.Widgets.data.nonce = nonces['update-widget'];
});
/**
* Init Customizer for widgets.
*/

File diff suppressed because one or more lines are too long

View File

@ -91,8 +91,8 @@ final class WP_Customize_Manager {
add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) );
add_action( 'setup_theme', array( $this, 'setup_theme' ) );
add_action( 'wp_loaded', array( $this, 'wp_loaded' ) );
add_action( 'setup_theme', array( $this, 'setup_theme' ) );
add_action( 'wp_loaded', array( $this, 'wp_loaded' ) );
// Run wp_redirect_status late to make sure we override the status last.
add_action( 'wp_redirect_status', array( $this, 'wp_redirect_status' ), 1000 );
@ -105,7 +105,8 @@ final class WP_Customize_Manager {
remove_action( 'admin_init', '_maybe_update_plugins' );
remove_action( 'admin_init', '_maybe_update_themes' );
add_action( 'wp_ajax_customize_save', array( $this, 'save' ) );
add_action( 'wp_ajax_customize_save', array( $this, 'save' ) );
add_action( 'wp_ajax_customize_refresh_nonces', array( $this, 'refresh_nonces' ) );
add_action( 'customize_register', array( $this, 'register_controls' ) );
add_action( 'customize_register', array( $this, 'register_dynamic_settings' ), 11 ); // allow code to create settings first
@ -783,6 +784,34 @@ final class WP_Customize_Manager {
wp_send_json_success( $response );
}
/**
* Refresh nonces for the current preview.
*
* @since 4.2.0
*/
public function refresh_nonces() {
if ( ! $this->is_preview() ) {
wp_send_json_error( 'not_preview' );
}
$nonces = array(
'save' => wp_create_nonce( 'save-customize_' . $this->get_stylesheet() ),
'preview' => wp_create_nonce( 'preview-customize_' . $this->get_stylesheet() ),
);
/**
* Filter nonces for a customize_refresh_nonces AJAX request.
*
* @since 4.2.0
*
* @param array $nonces Array of refreshed nonces for save and
* preview actions.
* @param WP_Customize_Manager $this WP_Customize_Manager instance.
*/
$nonces = apply_filters( 'customize_refresh_nonces', $nonces, $this );
wp_send_json_success( $nonces );
}
/**
* Add a customize setting.
*

View File

@ -95,6 +95,7 @@ final class WP_Customize_Widgets {
add_action( 'customize_controls_print_footer_scripts', array( $this, 'print_footer_scripts' ) );
add_action( 'customize_controls_print_footer_scripts', array( $this, 'output_widget_control_templates' ) );
add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ) );
add_filter( 'customize_refresh_nonces', array( $this, 'refresh_nonces' ) );
add_action( 'dynamic_sidebar', array( $this, 'tally_rendered_widgets' ) );
add_filter( 'is_active_sidebar', array( $this, 'tally_sidebars_via_is_active_sidebar_calls' ), 10, 2 );
@ -888,6 +889,20 @@ final class WP_Customize_Widgets {
add_action( 'wp_footer', array( $this, 'export_preview_data' ), 20 );
}
/**
* Refresh nonce for widget updates.
*
* @since 4.2.0
* @access public
*
* @param array $nonces Array of nonces.
* @return array $nonces Array of nonces.
*/
public function refresh_nonces( $nonces ) {
$nonces['update-widget'] = wp_create_nonce( 'update-widget' );
return $nonces;
}
/**
* When previewing, make sure the proper previewing widgets are used.
*

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.2-beta4-32053';
$wp_version = '4.2-beta4-32054';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.