-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Fetch: refresh nonces as soon as they expire, then fetch again #16683
Conversation
) | ||
), | ||
( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ) | ||
'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );' . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left createNonceMiddleware
alone as core is using it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious to have feedback from the REST API team on this one.
return reject( error ); | ||
} | ||
|
||
// If the nonce is invalid, refresh it and try again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can / should this be part of a new or existing middleware?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps. I didn't really find a good way to put the promise callback in the middleware for creating a request. I guess there should be two kinds of middleware then? One for creating the request and one for processing the response?
I'll make sure to bring this ticket up at the next office hours. |
@TimothyBJacobs Thanks! |
@TimothyBJacobs @kadamwhite Any news on this? :) |
@ellatrix Thanks for the bump :) My bad. I think this makes sense. I'd be very hesitant to change or relax the authentication rules for any route within My only concern would be to ensure we're guarded against any situation where the admin-ajax endpoint could be exploited by an unauthorized user to get a nonce/cookie combo they could use for mischief. I believe this is probably well in hand given normal admin-ajax authentication rules, I'm just much less familiar with those than I am the REST API! :) As for whether this should be middleware, I'm impartial. I feel it should be possible to utilize middleware for this, but |
'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );' . | ||
'wp.apiFetch.nonceEndpoint = "%s";', | ||
( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ), | ||
admin_url( 'admin-ajax.php?action=gutenberg_rest_nonce' ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the nonce lifetime could even be reduced for increased security, without affecting the user experience!
This would only be true if we assume all libraries are using apiFetch
, or at minimum using a similar base mechanism for refreshing nonces. Perhaps it would be better to drop the gutenberg_
prefix here to encourage consistent use of this approach by plugins writing admin UI that uses alternative HTTP transports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention is to drop the gutenberg_
prefix, but only when the PHP code gets merged with core. I'm also fine dropping it here, but this is still a plugin, not core.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would only be true if we assume all libraries are using apiFetch, or at minimum using a similar base mechanism for refreshing nonces.
That's right. It's currently also not possible to change the lifetime of specific nonces I think. That would be cool. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanted to highlight the possibility, but yes, right now, that's unrealistic.
@kadamwhite Thanks for the review. So if I understand you correctly, you have no objections? I also don't really care about the middleware. I can do it if people like, or we can just do it when the need arises. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if I understand you correctly, you have no objections?
Sorry for being vague; yes, I approve of the plan :) haven’t tested it locally but the code and direction sound great so I’ll add my +1 here
6f454ac
to
240815f
Compare
240815f
to
c62b839
Compare
Thanks for the review @kadamwhite! Let's iterate if we see a need for response middleware. This is a great step forward in ensure the user doesn't lose their content. :) |
I'll help out if this needs some renaming/adjustments on the PHP side when merging into core. |
…16683) * API Fetch: refresh nonces as soon as they expired, then fetch again * Use exit() * Fix PHP linting errors
…16683) * API Fetch: refresh nonces as soon as they expired, then fetch again * Use exit() * Fix PHP linting errors
@ellatrix do you know if this change have been packported into Core (the php change) or whether it's included in the last patch here https://core.trac.wordpress.org/ticket/47843 cc @gziolo |
It's not backported: @ellatrix @kadamwhite - should it be replicated as is in WordPress core? |
I'll try to look today, if not tomorrow (Monday). |
@gziolo The package hasn't been updated yet in core so it wouldn't have been adjusted it the core repository yet. |
I'll update you patch https://core.trac.wordpress.org/ticket/47843 |
Awesome, thank you for your help 💯 |
This is a follow up to #47843, implementing a PHP endpoint and inline scripts after the editor package updates. The action was originally added in WordPress/gutenberg#16683. Fixes #48076. git-svn-id: https://develop.svn.wordpress.org/trunk@46253 602fd350-edb4-49c9-b593-d223f7449a82
This is a follow up to #47843, implementing a PHP endpoint and inline scripts after the editor package updates. The action was originally added in WordPress/gutenberg#16683. Fixes #48076. git-svn-id: https://develop.svn.wordpress.org/trunk@46253 602fd350-edb4-49c9-b593-d223f7449a82
This is a follow up to #47843, implementing a PHP endpoint and inline scripts after the editor package updates. The action was originally added in WordPress/gutenberg#16683. Fixes #48076. Built from https://develop.svn.wordpress.org/trunk@46253 git-svn-id: http://core.svn.wordpress.org/trunk@46065 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This is a follow up to #47843, implementing a PHP endpoint and inline scripts after the editor package updates. The action was originally added in WordPress/gutenberg#16683. Fixes #48076. Built from https://develop.svn.wordpress.org/trunk@46253 git-svn-id: https://core.svn.wordpress.org/trunk@46065 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This is a follow up to #47843, implementing a PHP endpoint and inline scripts after the editor package updates. The action was originally added in WordPress/gutenberg#16683. Fixes #48076. git-svn-id: http://develop.svn.wordpress.org/trunk@46253 602fd350-edb4-49c9-b593-d223f7449a82
Description
Currently, nonces are refresh through the Heartbeat API, but it requires a valid nonce. When you leave a post open and come back to it the next day (during which time the heartbeat may have stopped), the nonce cannot be refreshed.
Since a simple authenticated request is enough to get a new nonce elsewhere (like a full page reload), we can just create an endpoint with
admin-ajax.php
to get a new nonce. We CANNOT use the REST API itself because of CORS, but we can create a separate endpoint without CORS.I updated the API Fetch package to refresh a nonce when the REST API sends a nonce error code. Once a new nonce is obtained, the request is remade. The user wouldn't notice a thing. :)
Notice that with this technique, the nonce lifetime could even be reduced for increased security, without affecting the user experience!
How has this been tested?
Install the e2e test plugin that sets the nonce lifetime to 5 seconds. Create a new post. Wait 5 seconds, then add some text and try to save. Saving should work. Open the console and notice that there is one 403 status error logged.
Screenshots
Types of changes
Checklist: