If you are using Safari or Chrome, the pre-fetch/pre-render can cause a duplicate request to be sent in the background. You can get a race condition where the tokens for the pre-fetched request are the ones stored in the session causing the mis-match. Hope this helps!
Why does the Twitter Socialite Provider hate me?
// Step 1 - ALL IS GOOD AND WE ARE OFF!!
$this->socialite->driver($provider)->redirect();
Which then starts the first part of OAuth 1.0 authentication to retrieving temporary credentials.
public function redirect()
{
$this->request->getSession()->set(
'oauth.temp', $temp = $this->server->getTemporaryCredentials()
);
Firs part of this is great. If you run Session::get('aouth,temp ') you will see the temp credentials. The 2nd part of this method also works fine. FYI - it redirects you to Twitter auth page as promised and you end up on a twitter screen that asks for authorization.
return new RedirectResponse($this->server->getAuthorizationUrl($temp));
}
You then approve auth on the twitter site and more good news - it returns a valid oauth_token and oauth_verifier.
// Step 3 - YES SIR, WE HAVE A RETURN REDIRECT WITH VALID TOKEN & VERIFIER! HOUSTON WE ARE A GO FOR BURN
Then you make a call to 2nd part of the Socialite core methods to get the user credentials with a user method call:
$this->socialite->driver($provider)->user();
It begins with the user() method in AbtractProvider class in on oauth1 socialite directory.
public function user()
{
if ( ! $this->hasNecessaryVerifier())
{
throw new \InvalidArgumentException("Invalid request. Missing OAuth verifier.");
}
the first part i.e. the above works fine as I can verify I a have token and verifier, from teh Twitter redirect. The user mthod has a call to get token.
$user = $this->server->getUserDetails($token = $this->getToken());
the getToken() method also in the oauth1 abstractprovider gets the temp oauth which succeeds, but not really as the temp oauth are not the original credentials.
protected function getToken()
{
$temp = $this->request->getSession()->get('oauth.temp');
it is then passes the temp creditentials to getTokenCredentials() method below in server.php League\OAuth1 where it breaks. As somewhere along the path it has done a redirect and reset the temp aouth credentials. I don't know where and been pulling my hair out trying to find the source of this 2nd temp creditentials call.
return $this->server->getTokenCredentials(
$temp, $this->request->get('oauth_token'), $this->request->get('oauth_verifier')
);
}
So the temp oauth are not the same as the same as the very first socialite ->redirect() and it throws up the man-in-middle warning.
public function getTokenCredentials(TemporaryCredentials $temporaryCredentials, $temporaryIdentifier, $verifier)
{
if ($temporaryIdentifier !== $temporaryCredentials->getIdentifier()) {
throw new \InvalidArgumentException(
"Temporary identifier passed back by server does not match that of stored temporary credentials.
Potential man-in-the-middle."
);
}
Don't read below because you will never get to experience the a world full of user data yummy. Above is coach and below is first class. That said I do wonder what wonders lie in this Wonka factory of Chocolate covered twitter user data, but I will never know because it hates me
// Now, we'll store the token credentials and discard the temporary
// ones - they're irrelevant at this stage.
unset($_SESSION['temporary_credentials']);
$_SESSION['token_credentials'] = serialize($tokenCredentials);
session_write_close();
// Redirect to the user page
header("Location: http://{$_SERVER['HTTP_HOST']}/?user=user");
exit;
if (isset($_GET['user'])) {
Please or to participate in this conversation.