protected function finishAuthentication(Request $httpRequest)
    {
        $sessionCode = $this->session->get("oauth2state");
        $this->session->remove("oauth2state");

        // Check that the state from OAuth response matches the one in the session
        if ($httpRequest->query->get("state") !== $sessionCode) {
            $this->onStateMismatch();
        }

        // Returns one of https://tools.ietf.org/html/rfc6749#section-4.1.2.1
        if ($httpRequest->query->has("error")) {
            $this->onOAuthError($httpRequest->query->get("error"));
        }

        // Error not set, but code not present (not an RFC complaint response)
        if (!$httpRequest->query->has("code")) {
            $this->onOAuthError("no_code");
        }

        try {
            $accessToken = $this->provider->getAccessToken('authorization_code', [
                'code' => $httpRequest->query->get("code"),
            ]);

            $resourceOwner = $this->provider->getResourceOwner($accessToken);

            $this->saveLoginInfo($resourceOwner);
        } catch (IdentityProviderException $e) {
            $this->onOauthResourceError($e);
        }
    }