-
Notifications
You must be signed in to change notification settings - Fork 121
REST API: Custom cookie nonce authenticator #8659
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
Conversation
You can test the changes from this Pull Request by:
|
jaclync
left a comment
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.
Login works with multiple Pressable sites! had some clarifying questions, feel free to merge to unblock testing other PRs
| /// Authenticates and retries requests | ||
| /// | ||
| final class RequestProcessor { | ||
| final class ApplicationPasswordRequestProcessor { |
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.
Maybe @selanthiraiyan can confirm the renaming of these classes since you created them? I didn't know they're only used in the application password context when I reviewed the previous PR on these classes.
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 processor triggers generating application passwords when retrying requests, so it is specific to application password authentication only. I renamed this to avoid confusion with any other authentication method.
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 am afraid that using ApplicationPassword as a prefix wouldn't make sense here.
The RequestProcessor handles authentication for both WPCOM token and application password cases. RequestProcessor uses DefaultRequestAuthenticator to perform the authentication here
Extra info: Only REST requests are retried, and errors from other requests are just passed through. Due to this method in AlamofireNetwork
|
|
||
| /// RequestProcessor Unit Tests | ||
| /// | ||
| final class RequestProcessorTests: XCTestCase { |
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.
nit: do we want to rename the test case name & file name as well?
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.
Good catch, updated in d820410.
| // If we can't get this to work once, don't retry for the same site | ||
| // It is likely that there is something preventing us from extracting a nonce | ||
| private var canRetry = true |
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 comment seems to contradict the code canRetry = true? 🤔 my interpretation of the comment is that we're not retrying.
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 comment is meant to say that we should allow retrying only once, but I've removed the comment since it can be misleading.
| // MARK: Request Adapter | ||
|
|
||
| func adapt(_ urlRequest: URLRequest) throws -> URLRequest { | ||
| guard let nonce = nonce else { |
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.
super nit:
| guard let nonce = nonce else { | |
| guard let nonce else { |
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.
Done in 22c6ef0.
| import Alamofire | ||
| import Foundation | ||
|
|
||
| final class CookieNonceAuthenticator: RequestRetrier & RequestAdapter { |
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.
it'd be helpful to have some notes on the differences from the implementation in WordPressKit, so that it's easier to understand the changes since most of us aren't familiar with the cookie nonce auth 🙂
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.
| let nonceRequest = try? URLRequest(url: nonceRetrievalURL, method: .get) else { | ||
| return invalidateLoginSequence(error: .invalidNewPostURL) | ||
| } | ||
| Task(priority: .medium) { |
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.
❓ how is the priority determined? just thought the login request might be the top priority so that the user can log in.
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 think for networking requests, we want to use priorities lower than .userInitiated to avoid blocking the UI. .medium is my go-to for higher-priority networking requests - I hope that makes sense.
| } | ||
|
|
||
| func buildNonceRequestURL(base: URL) -> URL? { | ||
| URL(string: "admin-ajax.php?action=rest-nonce", relativeTo: base) |
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.
❓ when I was comparing the implementation with the WordPressKit version, there was a check on version 5.3.0 (I assume it's the WP version) to use the ajax URL. just confirming that we don't need this check anymore?
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.
That's true, we want to support only sites with WP from 5.6.0 to handle application passwords. This means only ajax nonce retrieval is needed. I updated the comment for the authenticator in 67ec443.
| var parameters = [URLQueryItem]() | ||
| parameters.append(URLQueryItem(name: "log", value: username)) | ||
| parameters.append(URLQueryItem(name: "pwd", value: password)) | ||
| parameters.append(URLQueryItem(name: "rememberme", value: "true")) |
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.
❓ it looks like the request does not include a redirect_to URL anymore from the WPKit implementation, is it one of the major changes that fix the issue?
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.
Yes, that's the objective for this PR 😄.
| guard !html.isEmpty else { | ||
| return nil | ||
| } | ||
| return html |
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.
nit: maybe can simplify?
| guard !html.isEmpty else { | |
| return nil | |
| } | |
| return html | |
| html.isEmpty ? nil: html |
|
I'm merging this PR to avoid blocking other PRs. @selanthiraiyan - if there's any issue with the renaming, I'll update it in a future PR. |
|
Thanks for the ping @itsmeichigo ! I am afraid that adding |
Part of #8453
Description
There has been an ongoing issue with handling cookie-nonce authentication for Pressable sites (also mentioned by @joshheald in #8587). This blocks testing for these sites and can be an issue on production as well (though not reproducible or reported yet).
Previously we were using
WordPressKit'sCookieNonceAuthenticatorto handle the authentication, but there's a potential issue with using the cookie nonce retrieval URL as the redirect URL for the login request.This PR creates an updated authenticator that handles nonce retrieval as a separate request. This seems to fix the failures on Pressable sites. I'm not creating a PR to
WordPressKitto avoid affecting other apps that are using this library.Also: in order to avoid confusion, this PR also renames the existing
RequestAuthenticator,RequestProcessorwith theApplicationPasswordprefix.Due to time constraints, unit tests for the authenticator will be added in a future PR.
Testing instructions
Pre-requisite: Make sure that you have a test site hosted on Pressable.
applicationPasswordAuthenticationForSiteCredentialLoginand build the app.Screenshots
N/A
RELEASE-NOTES.txtif necessary.