How do I redirect successfully registered user to the page he was reading before login - wordpress

I've a registration system which redirects user to specific page lets say success.php
In this page I've custom script that sends out Welcome mail to the user and posts success on facebook since registration is through FB oath.
I would like to redirect success.php to the original page user was reading before asking for registration/login.
How do I do this?
I'm using Wordpress as CMS if its helpful.
Would something like this work in all situations?
$_SERVER['HTTP_REFERER']

There are many ways to redirect users in Wp the simplest one being :
wp_redirect() (HERE) which has 2 parameters :
$location = The absolute URI to which the user will be redirected. No default.
$status = The status code to use. For example, 301, 302, etc. The default is 302.
wp_redirect('http://mywebsite.com/',302);
Note that it is also pluggable.
Then you have
auth_redirect();
which is basically the same but requires login before giving access - no parameters
you also have a login_redirect filter which you can use ,but i am not sure it is for your case as described.

Related

Symfony - Target path is null on cURL like user request

I have an application with restricted access to the whole site, except for login and password recovery.
I'm trying to add to the login view open graph meta tags with data based on the referer address. To do that, I use the \Symfony\Component\Security\Http\Util\TargetPathTrait in the login action like this:
<?php
$referer = $this->getTargetPath($request->getSession(), 'main');
Locally, I use Open Graph Preview chrome add-on, and it works perfectly. As an anonymous user, I try to acces to a page, and then redirected to the login page. Here $referer is not null and I can retieve data I need to generate meta tags.
Now on test environment on my production server, with open graph chrome add-on, it still working. Share a link through Telegram, the preview is displayed as expected. But when I share the same link through Facebook messenger, I don't get what I want.
Edit: doesn't work with Discord and WhatsApp either.
I've made some test with the Facebook debugger, it appears that $referer is null and I don't understand why. It looks like Symfony access control have a particular behavior when a Facebook service try to see a page, as no session data seems to be manage by the symfony security components.
The login feature of the application is quite simple as it follows the basics step described in the Symfony documentation.
Is anyone has a clue on what can I do to fix that? Meanwhile, I'm trying to find a workaround with Symfony events.
EDIT 1: I reproduced the issue localy, with a cURL request. In that case it appears no session is handled. \Symfony\Component\Security\Http\Util\TargetPathTrait::getTargetPath method is useless as Symfony store the target path in session.
So now, when an anonymous user try to request a restricted URL, I add the referer as a GET parameter to the redirect login URL.
Cool thing, now the preview works perfectly on Discord, WhatsApp and still works on Telgram.
Sadly, it still doesn't work on Facebook's app (Messenger and Facebook posts).
So, I took a look on the facebook debugger tool. And here come the strange thing, the redirect url request by FB service is different than the one my application normally give.
Expected URL : https://domain.ext/login?referer=https://domain.ext/referer/path
URL requested by FB : https://domain.ext/login?randomCoherentParamName=intValue
The odd thing is that 'randomCoherentParamName' correspond to a route parameter from the referer URL.
Here how I generate the redirect URL:
<?php
// From a class that extends
// Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator
/**
* Override to control what happens when the user hits a secure page
* but isn't logged in yet.
*
* #return RedirectResponse
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$url = $this->urlGenerator->generate('loginRoute', ['referer' => $request->getUri()]);
return new RedirectResponse($url);
}
If anyone has a clue of what's going on, I will appreciate any advice :).
EDIT 2: It seems FB service use a canonical URL to access the login page when redirected. Problem is I never set the canonical address meta tag in any page on my website. So, I'm wondering how is it possible...
Anyway, I think I've got a solution to bypass this problem, I'll share if it works, but I really want to understand how FB service works and identify how it is able to get a canonical URL I've never set... Apach fault? Symfony fault? My Fault? Or is it related to the Facebook crawler ?
Any comment will be appreciate :)
Problem solved !
The Facebook issue was totally my fault, actually, and a bit because of FB service. Let me explain.
When FB service request a shared URL, it parses the response to find open graph meta tags. During response parsing, if the service detect an url open graph meta tag, it request that url and use the parsed data from that response to generate the preview. This behavior seems to be specific to Facebook, as I didn't have any issue with Discord, WhatsApp and Telegram (and Telegram handle session when it retrieve data from an URL).
Now, what did I do wrong ? Actually, my login page has an url open graph meta tag, and, well... I didn't generate the good URL as its value...
Thanks for your attention :)

Logins and Redirects: What is the best HTTP flow for a webapp login?

This question is a question about login flows for web-apps in general. I'm most interested in answers that optimize for usability and performance while maintaining security.
What is the most appropriate way to handle unauthenticated requests to bookmarked URLs?
To demonstrate the problem, here are some routes and respective behaviors for an example application:
GET /login -> Display the authentication form
POST /processLogin -> process the username and password,
if unauthentic...re-render the login form;
otherwise...display the default page
GET /secret -> if authenticated...display the secret resource;
otherwise...display a login form
POST /secret -> if authenticated...perform a desirable, but potentially
non-idempotent action on the secret
resource
otherwise...display a login form
Option 1: Display login screen, redirect to desired page
User clicks bookmark
GET /secret -> 200, surreptitiously display login form with hidden field path="/secret"
POST /processLogin -> 302 to /secret (value of path parameter)
GET /secret -> 200, secret resource displayed
Analysis: Hopefully, your client is a modern browser, non-compliant with HTTP, such that it performs a GET after a 302'd POST. This applies across the board. Should I be worried?
Option 2: Redirect to login screen, redirect to desired page
User clicks bookmark
GET /secret -> 302 to /login
GET /login via redirect -> 200, login form displayed with hidden field path="/secret"
POST /processLogin -> 302 to /secret
GET /secret -> 200, secret resource displayed
Analysis: Same problems as above. Added problem that the URL displayed by the browser during login changes, which is confusing to the user and breaks bookmarking, link sharing, etc.
Option 3: Display login screen, display desired page
User clicks bookmark
GET /secret -> 200, surreptitiously display login form with action="/secret"
POST /secret -> 200, secret resource displayed
Analysis: Sadly, the refresh button is now also broken: refresh will cause the user agent to re-POST with a warning, instead of re-GETing /secret. They user gets a warning, but if they ignore it, something bad happens.
On the bright side, you minimize roundtrips with this technique.
Option 4: Redirect to login screen, display desired page
User clicks bookmark
GET /secret -> 302 to /processLogin
GET /processLogin via redirect -> 200, login form displayed with action="/secret"
POST /secret -> 302 to /secret
GET /secret -> 200, secret resource displayed
Analysis: Same problems as options 2+4.
Option 5: ???
Is there another technique I'm missing?
In general, which of these techniques would you recommend?
See Also
What is correct HTTP status code when redirecting to a login page?
What kind of HTTP redirect for logins?
HTTP response with redirect, but without roundtrip?
Option 1 & 3 are not following the HTTP RFC as "surreptitiously display login form" contradicts 200 GET response, where "an entity corresponding to the requested resource is sent in the response" is expected.
Option 2 is OK. All modern browsers support 302 on POST and many REST-based frameworks (like RoR) actively use it. Alternatively in "302 to /login" you can already create the session (cookie) and store the URL in session, to avoid passing the original URL in GET parameters. From usability standpoint, you can have an appropriate message on login page too (I think the URL mismatch is irrelevant here - you can't let the user see the content anyway).
Option 4: when you POST to /secret, HTTP RFC expects you to "accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line", but all you are doing is logging in and not creating anything new under /secret.
So following HTTP RFC, your best choice is Option 2. Actually Option 2 is also in line with POST->Redirect->GET design pattern, which helps to address the issue of unpredictability in bookmarking URLs to POST'ed resources.
My $.02: I recently implemented using option 2 (although I stored /secret in a session, not in the login form as a hidden field).
I don't entirely share your concerns:
Added problem that the URL displayed
by the browser during login changes, which is confusing to the user
and breaks bookmarking, link sharing, etc.
Redirecting to /login, and the subsequent change of URL, tells the user that before they can continue there's something else that needs to be done first: logging in.
Since a login page will look entirely different from the 'target page', I don't see how that will confuse people into bookmarking and/or link sharing the login page instead of the target page (since the login page won't contain the information they want to bookmark/share anyway).
And if you're worried about 302's breaking the standard (although every single browser I know will happily break it), consider using 303's instead.
Note that mickeyreiss is correct, using AJAX Option 3 works without the drawback of the broken back button. However, it means the user has to have JavaScript enabled. This being said, if you program your form properly, you can detect whether JS is present, if not use Option 1.
Note that the 302 response is fine, however, you may have problems with caches. You have to make sure that nothing gets cached if you want to show 2 completely different pages/forms on for the same URI. (/secret showing the login and then the actual secret.)
I almost always use option #2, simply because the content returned by a URL is consistent. While today's secrets are hidden behind a login, tomorrow you may want to open it up or display mixed public/secret depending on authentication at the same URL. In that case, option #2 will be most like what Google would expect. Any content bait and switch is looked down on by Google and in the extreme case, all of your pages would have duplicate page content (ie. login form).
I would choose the option using AJAX:
login page and hide the content
the user enters the login and the password.
Authentication is done in the server side.
The server returns a result
if successful use location.href to set the page you would like to
go to, or else you can output a message saying the login is not
valid.
In your server you will be testing on a _SESSION variable, if not set redirect to the login page..

Inviting Facebook friends to custom uri

I wonder if it's possible to use FB.ui to invite friends to a custom page of my web application, but not to it's index.
Apprequests method doesn't seem to have any parameters as customizable uri
FB.ui({method: 'apprequests',
message: 'yay!',
});
In case if it's impossible to achieve with FB.ui, I would be glad to accept any other options. Thanks in advance.
By default, the invite will always send the user to the default canvas URL for your application. What you should do is detect this URL on the Index page, and then redirect them where you actually want them to go.
The way to do this is to look for the request_ids in the URL ($_GET) and then do a API call to /$request_id to verify it. Then you can redirect the user to any page you want (either JavaScript redirect, or PHP header redirect).

In WordPress, how do I get the "redirect_to" URL argument to include the path & arguments of the original page for redirecting after logging in?

I have a custom folder called /portal/ that takes arguments like /portal/?id=123 or /portal/?id=321 etc.
In the /portal/index.php file I included the following which automatically redirects users to the WP login if the user is not authenticated.
include_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );
If not logged in they are automatically redirected to http://www.domain.com/wp-login.php?redirect_to=http%3A%2F%2Fwww.domain.com%2F&reauth=1.
How do I fix the redirect_to argument so it includes the path and arguments? I want the redirect to look like this:
http://www.domain.com/wp-login.php?redirect_to=http%3A%2F%2Fwww.domain.com%2Fportal%2F?id%3D123&reauth=1
This way, once the user logs in, they will be redirected to the page they were trying to access in the first place.
First, including wp-load.php isn't recommended - Don't include wp-load, please - for several reasons.
Presumably you have Wordpress configured to require a login, which is why are you are getting a redirect to the login page, and because it is happening directly from your include, you can't insert any filters to change the redirect before it's loaded, and using them afterwards is moot because the redirect will have already fired.
If this was constructed as a plugin it would be loaded by wp-load, and you would have access to the login_url filter, which you can use to add a redirect as in this example: http://trepmal.com/filter_hook/login_url/.
I was able to come up with a hack that checks for the existence of a cookie key begining with wordpress_logged_in_. If the cookie key doesn't exist then I redirect to the login page to http://www.domai.com/wp-login.php?redirect_to=http%3A%2F%2Fwww.domain.com'.urlencode($_SERVER['REQUEST_URI']).

Drupal : customize status messages (of contact form)

I am setting up a website using drupal 6 and trying to be minimalistic. I use contact form, and it works pretty well. Once the message is sent, it is redirected to the front page of my site with a message "Your message has been sent.".(with a div messages status). How can one change it like,
customize the message content
instead of redirecting to the home page, display a node (another page)
thanks for any suggestion.
For more advanced forms and customisation like you mention above, you should try webform. Webform has the ability to redirect a successful submission to another URL and have a custom status message as well.
Change the string for the message. To do that, you can either turn on the locale.module or get string overrides module.
You can create a small custom module to redirect the user using the #redirect property of the Forms API. See here for an example (and check the comments for potential issues).
Alternatively, consider using one of these modules:
Node Destination
Custom (Form) Destination
Rules
Page manager redirect

Resources