REST API JS Client: Improve nonce handling, refresh stale nonce on sync.

Keep the nonce used for cookie based authentication fresh by pulling in and using any new nonce supplied in the response headers.

* Enable passing nonce to init so each api/endpoint can use a unique nonce.
* Store nonce for endpoint on endpointModel.
* New model helper `nonce()` retrieves a model's routeModel nonce.
* When a response header contains a nonce that doesn't match the stored nonce, replace it.

Fixes #40422.

Built from https://develop.svn.wordpress.org/trunk@41553


git-svn-id: http://core.svn.wordpress.org/trunk@41386 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Adam Silverstein 2017-09-21 12:58:45 +00:00
parent 9aeedde6ae
commit 639d215300
3 changed files with 33 additions and 6 deletions

View File

@ -793,19 +793,29 @@
model.unset( 'slug' ); model.unset( 'slug' );
} }
if ( ! _.isUndefined( wpApiSettings.nonce ) && ! _.isNull( wpApiSettings.nonce ) ) { if ( _.isFunction( model.nonce ) && ! _.isUndefined( model.nonce() ) && ! _.isNull( model.nonce() ) ) {
beforeSend = options.beforeSend; beforeSend = options.beforeSend;
// @todo enable option for jsonp endpoints // @todo enable option for jsonp endpoints
// options.dataType = 'jsonp'; // options.dataType = 'jsonp';
// Include the nonce with requests.
options.beforeSend = function( xhr ) { options.beforeSend = function( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce ); xhr.setRequestHeader( 'X-WP-Nonce', model.nonce() );
if ( beforeSend ) { if ( beforeSend ) {
return beforeSend.apply( this, arguments ); return beforeSend.apply( this, arguments );
} }
}; };
// Update the nonce when a new nonce is returned with the response.
options.complete = function( xhr ) {
var returnedNonce = xhr.getResponseHeader( 'X-WP-Nonce' );
if ( returnedNonce && _.isFunction( model.nonce ) && model.nonce() !== returnedNonce ) {
model.endpointModel.set( 'nonce', returnedNonce );
}
};
} }
// Add '?force=true' to use delete method when required. // Add '?force=true' to use delete method when required.
@ -1048,6 +1058,7 @@
defaults: { defaults: {
apiRoot: wpApiSettings.root, apiRoot: wpApiSettings.root,
versionString: wp.api.versionString, versionString: wp.api.versionString,
nonce: null,
schema: null, schema: null,
models: {}, models: {},
collections: {} collections: {}
@ -1065,8 +1076,9 @@
model.schemaConstructed = deferred.promise(); model.schemaConstructed = deferred.promise();
model.schemaModel = new wp.api.models.Schema( null, { model.schemaModel = new wp.api.models.Schema( null, {
apiRoot: model.get( 'apiRoot' ), apiRoot: model.get( 'apiRoot' ),
versionString: model.get( 'versionString' ) versionString: model.get( 'versionString' ),
nonce: model.get( 'nonce' )
} ); } );
// When the model loads, resolve the promise. // When the model loads, resolve the promise.
@ -1238,6 +1250,13 @@
return url; return url;
}, },
// Track nonces on the Endpoint 'routeModel'.
nonce: function() {
return routeModel.get( 'nonce' );
},
endpointModel: routeModel,
// Include a reference to the original route object. // Include a reference to the original route object.
route: modelRoute, route: modelRoute,
@ -1284,6 +1303,13 @@
return url; return url;
}, },
// Track nonces at the Endpoint level.
nonce: function() {
return routeModel.get( 'nonce' );
},
endpointModel: routeModel,
// Include a reference to the original route object. // Include a reference to the original route object.
route: modelRoute, route: modelRoute,
@ -1405,6 +1431,7 @@
var endpoint, attributes = {}, deferred, promise; var endpoint, attributes = {}, deferred, promise;
args = args || {}; args = args || {};
attributes.nonce = args.nonce || wpApiSettings.nonce || '';
attributes.apiRoot = args.apiRoot || wpApiSettings.root || '/wp-json'; attributes.apiRoot = args.apiRoot || wpApiSettings.root || '/wp-json';
attributes.versionString = args.versionString || wpApiSettings.versionString || 'wp/v2/'; attributes.versionString = args.versionString || wpApiSettings.versionString || 'wp/v2/';
attributes.schema = args.schema || null; attributes.schema = args.schema || null;

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '4.9-alpha-41552'; $wp_version = '4.9-alpha-41553';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.