Fix login error messages not displaying when redirect_to is present#3576
Fix login error messages not displaying when redirect_to is present#3576sacrefizz wants to merge 1 commit intostrangerstudios:devfrom
Conversation
When a user is redirected to the PMPro login page with a redirect_to parameter (e.g., after trying to access a members-only page), failed login attempts do not show error messages. This happens because redirect_to is passed directly to wp_login_form() as a hidden field, which wp-login.php uses during the authentication flow, interfering with PMPro's error message display. This fix separates PMPro's redirect handling from wp_login_form's redirect_to hidden field by using a dedicated pmpro_redirect_to hidden field. The pmpro_login_redirect() and pmpro_login_failed() functions are updated to read from this new field first, with a fallback to redirect_to for backwards compatibility.
|
Hi @sacrefizz, thank you for submitting this pull request. I have followed the steps to reproduce this issue, but was not able to replicate the behavior. By default in PMPro, when a logged out user visits a restricted post, they will not automatically be redirected to the login page. They will instead be shown a message allowing them to either purchase access or log in. When testing, I decided to log in via the restricted content message which did set the Especially given the fact that your site is redirecting users away from restricted content, it sounds like your site may be running other plugins or custom code that may be contributing to this behavior. Can you please confirm whether you can replicate this issue with only PMPro active? If this issue requires other PMPro Add Ons to be active in order to replicate, can you please let me know which plugins are required so that we can test further? |
|
Thanks for testing @dparker1005! The redirect in my case comes entirely from PMPro's own mechanism — no custom redirect code is involved. The flow: A logged-out user visits The issue was severe enough that I had to write a workaround plugin that strips the Could the difference be the block vs shortcode? I'm using PMPro 3.6 with the Gutenberg block. Could you confirm which version and which login method (block or shortcode) you tested with? I'm happy to deactivate my workaround plugin and test with only PMPro active. I'll report back with the results. |
|
Hi there @sacrefizz, Thank you for clarify that the redirect occurred when trying to access the PMPro Account page. I was now able to replicate this redirect on my testing site; however when testing a login with an incorrect password, I am still seeing the error. I have tried using both the PMPro login page shortcode and block. If you are able to replicate this behavior on your site with only PMPro active, or find any other information that may help us to replicate this behavior on our end, please let me know and we can take another look. |
flintfromthebasement
left a comment
There was a problem hiding this comment.
PR: #3576 — Fix login error messages not displaying when redirect_to is present
sacrefizz → dev | 1 file, +37 -1
#3576
Summary
Correct root cause diagnosis and a clean fix. Separating PMPro's redirect tracking from wp_login_form()'s native redirect_to field is the right approach. The round-trip logic holds: failed login embeds the URL as a query param back to the PMPro login page, which re-injects it into the pmpro_redirect_to hidden field on re-render. Ready to merge with two minor items noted below.
Issues
-
Minor
includes/login.php:~20(pmpro_login_redirect) —pmpro_redirect_tois accepted from$_REQUESTand overwrites$redirect_towithout validating the host. WordPress core downstream useswp_safe_redirect()which prevents the open redirect in practice, but thepmpro_login_redirect_urlfilter exposes the raw value to callers before that safety net kicks in. Defensive fix: wrap withwp_validate_redirect( $value, home_url() )before assigning. -
Minor
includes/login.php:~1095(pmpro_login_failed) — Thepmpro_redirect_toread applieswp_unslash(), but the oldredirect_tofallback added two lines later does not. The pre-existing code didn't have it either, so this isn't a regression, but since you're touching this line, worth making consistent:$redirect_to = ( ! empty( $_REQUEST['redirect_to'] ) ) ? esc_url_raw( wp_unslash( $_REQUEST['redirect_to'] ) ) : '';
Looks Good
- The closure approach for
login_form_bottomis correct — storing a reference to the closure and passing it toremove_filter()is exactly how anonymous filter cleanup works in PHP. No filter leakage between multiplepmpro_login_form()calls on the same page. unset( $args['redirect'] )before passing towp_login_form()is the cleanest way to prevent the hidden field collision without patching core behavior.- Backwards compatibility preserved in
pmpro_login_failed()via theredirect_tofallback.
Summary
When a user is redirected to the PMPro login page with a
redirect_toparameter (e.g., after trying to access a members-only page), failed login attempts do not show error messages on the PMPro login page.Root cause
The
redirect_toURL is passed directly towp_login_form()via theredirectargument, which embeds it as a hiddenredirect_tofield in the form. When the form POSTs towp-login.php, thisredirect_tovalue interferes with the authentication flow, causing the error messages to be lost instead of being displayed on the PMPro login page.Fix
This PR separates PMPro's redirect handling from
wp_login_form()'sredirect_tohidden field:pmpro_login_form(): Extracts the redirect URL from the args before callingwp_login_form(), and adds it as a separatepmpro_redirect_tohidden field via thelogin_form_bottomfilter.pmpro_login_redirect(): Checkspmpro_redirect_tofirst for successful login redirects.pmpro_login_failed(): Checkspmpro_redirect_tofirst when preserving the redirect URL across failed login attempts, with a fallback toredirect_tofor backwards compatibility.How to reproduce
/login/?redirect_to=%2Fmembers-page%2FTest plan