Search code examples
symfonyauthenticationfacebook-opengraphreferer

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 :)


Solution

  • 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 :)