Roland
Roland

Reputation: 313

HybridAuth authorization state error specifically only on mobile devices

Implemented the hybridauth/hybridauth package to connect social users (google / twitter / discord) to the site. All of them working on desktop, but if I want to call the google oauth2 client from a mobile (android) browser, it's keep failing:

The authorization state [state=HA-G691AZBT3M8OLX5KP0RNF...] of this page is either invalid or has already been consumed.

So again, it's work like a charm on desktop, even on iOS mobiles but android smartphones not.

The error comes from the authenticateFinish() where the process behind the authenticateCheckError(); so the provider (google) granted the access and we've got the code variable from the response:

public function authenticate()
{
    $this->logger->info(sprintf('%s::authenticate()', get_class($this)));

    if ($this->isConnected()) {
        return true;
    }

    try {
        $this->authenticateCheckError();

        $code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');

        if (empty($code)) {
            $this->authenticateBegin();
        } else {
            $this->authenticateFinish();
        }
    } catch (Exception $e) {
        $this->clearStoredData();

        throw $e;
    }

    return null;
}

and where it fails actually:

protected function authenticateFinish()
{
    $this->logger->debug(
        sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
        [HttpClient\Util::getCurrentUrl(true)]
    );

    $state = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'state');
    $code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');

    /**
     * Authorization Request State
     *
     * RFC6749: state : RECOMMENDED. An opaque value used by the client to maintain
     * state between the request and callback. The authorization server includes
     * this value when redirecting the user-agent back to the client.
     *
     * http://tools.ietf.org/html/rfc6749#section-4.1.1
     */
    if ($this->supportRequestState
        && $this->getStoredData('authorization_state') != $state
    ) {
        throw new InvalidAuthorizationStateException(
            'The authorization state [state=' . substr(htmlentities($state), 0, 100) . '] '
            . 'of this page is either invalid or has already been consumed.'
        );
    }

    /**
     * Authorization Request Code
     *
     * RFC6749: If the resource owner grants the access request, the authorization
     * server issues an authorization code and delivers it to the client:
     *
     * http://tools.ietf.org/html/rfc6749#section-4.1.2
     */
    $response = $this->exchangeCodeForAccessToken($code);

    $this->validateAccessTokenExchange($response);

    $this->initialize();
}

and somehow throws the InvalidAuthorizationStateException on android mobile. It was tested on 3 devices, all the same issue, i think we can exclude unique issue actually.

Does anybody mets the same error?

Upvotes: 1

Views: 473

Answers (1)

Michal Trojanowski
Michal Trojanowski

Reputation: 12342

My guess is that there is a problem either with storing state Android or with reading it. Can you debug what does the $this->getStoredData('authorization_state') method return? I would try to debug why it doesn't return the expected state. Also debug the method where the state is persisted before making an authorization request.

As it works on other platforms I would assume that there is a problem with porting the code to Android, or that the app is missing some permissions. Maybe it tries to write the state in a file and doesn't have permissions to do that?

Upvotes: 0

Related Questions