Ошибка при получении учетных данных OAuth: «Исключение OAuthException: был использован этот код авторизации».

#php #facebook #symfony #authentication #oauth

#php #Facebook #symfony #аутентификация #oauth

Вопрос:

Я нашел много руководств по этой проблеме. Но ни один из них не решил мою проблему. Итак, я пытаюсь использовать Symfony 4, чтобы следовать этому руководству для OAuth2 Facebook

Когда я нажимаю на свою кнопку «Связь с Facebook», у меня появляется пустая страница с сообщением :

Ошибка при получении учетных данных OAuth: «Исключение OAuthException: был использован этот код авторизации»..

Я видел в некоторых руководствах, что это проблема с accessToken, longliveAccessToken и т. Д.

Но я понятия не имею, что делать в моем коде, чтобы решить эту проблему.

Вот мой код моего FacebookAuthenticator.php :

     <?php

namespace AppSecurity;

use AppEntityUser; // your user entity
use DoctrineORMEntityManagerInterface;
use KnpUOAuth2ClientBundleSecurityAuthenticatorSocialAuthenticator;
use KnpUOAuth2ClientBundleClientProviderFacebookClient;
use KnpUOAuth2ClientBundleClientClientRegistry;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentSecurityCoreUserUserProviderInterface;

class FacebookAuthenticator extends SocialAuthenticator
{
    private $clientRegistry;
    private $em;

    public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $em)
    {
        $this->clientRegistry = $clientRegistry;
        $this->em = $em;
    }

    public function supports(Request $request)
    {
        // continue ONLY if the current ROUTE matches the check ROUTE
        return $request->attributes->get('_route') === 'connect_facebook_check';
    }

    public function getCredentials(Request $request)
    {
        // this method is only called if supports() returns true

        // For Symfony lower than 3.4 the supports method need to be called manually here:
        // if (!$this->supports($request)) {
        //     return null;
        // }

        return $this->fetchAccessToken($this->getFacebookClient());
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        /** @var FacebookUser $facebookUser */
        $facebookUser = $this->getFacebookClient()
            ->fetchUserFromToken($credentials);


        // 1) have they logged in with Facebook before? Easy!
        $existingUser = $this->em->getRepository(User::class)
            ->findOneBy(['facebookId' => $facebookUser->getId()]);
        if ($existingUser) {
            return $existingUser;
        }

        // 2) do we have a matching user by email?
        $user = $this->em->getRepository(User::class)
            ->findOneBy(['email' => $email]);

        // 3) Maybe you just want to "register" them by creating
        // a User object
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%amp;*_";

        if(!$user){
        $user = new User();
        }
        $user->setFacebookId($facebookUser->getId());
        $user->setUsername($facebookUser->getEmail());
        $user->setPassword(password_hash(substr( str_shuffle( $chars ), 0, 10), PASSWORD_DEFAULT));
        $user->setPrenom($facebookUser->getFirstName());
        $user->setNom($facebookUser->getLastName());
        $user->setEmail($facebookUser->getEmail());
        $user->setEnabled(true);
        $user->setSocialAuthentication(true);
        $this->em->persist($user);
        $this->em->flush();


        return $user;

    }

    /**
     * @return FacebookClient
     */
    private function getFacebookClient()
    {

        return $this->clientRegistry
            // "facebook_main" is the key used in config/packages/knpu_oauth2_client.yaml
            ->getClient('facebook_main');
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        // on success, let the request continue
        return null;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        $message = strtr($exception->getMessageKey(), $exception->getMessageData());

        return new Response($message, Response::HTTP_FORBIDDEN);
    }

    /**
     * Called when authentication is needed, but it's not sent.
     * This redirects to the 'login'.
     */
    public function start(Request $request, AuthenticationException $authException = null)
    {
        return new RedirectResponse(
            '/connect/', // might be the site, where users choose their oauth provider
            Response::HTTP_TEMPORARY_REDIRECT
        );
    }


}
 

Мой пользователь создан в моей базе данных с правильными данными, но не может пройти аутентификацию с его помощью.

Спасибо за помощь, если вам нужен код для FacebookController.php , скажите мне, тогда я отредактирую свой пост.

Редактировать :

введите описание изображения здесь

РЕДАКТИРОВАТЬ 2 :

 public function getUser($credentials, UserProviderInterface $userProvider)
    {
        /** @var FacebookUser $facebookUser */

        $client = $this->clientRegistry->getClient('facebook_main');
        $accessToken = $client->getAccessToken();
        if ($accessToken amp;amp; !$accessToken->getToken()) {
            dump("User is not found!"); die;
        }
        $provider = $client->getOAuth2Provider();
        $longLivedToken = $provider->getLongLivedAccessToken($accessToken);
        //I get the user by using long lived token
        $facebookUser = $client->fetchUserFromToken($longLivedToken);

        $email = $facebookUser->getEmail();

        // 1) have they logged in with Facebook before? Easy!
        $existingUser = $this->em->getRepository(User::class)
            ->findOneBy(['facebookId' => $facebookUser->getId()]);
        if ($existingUser) {
            return $existingUser;
        }

        // 2) do we have a matching user by email?
        $user = $this->em->getRepository(User::class)
            ->findOneBy(['email' => $email]);

        // 3) Maybe you just want to "register" them by creating
        // a User object
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%amp;*_";

        if(!$user) {
            $user = new User();
            $user->setFacebookId($facebookUser->getId());
            $user->setUsername($facebookUser->getEmail());
            $user->setPassword(password_hash(substr(str_shuffle($chars), 0, 10), PASSWORD_DEFAULT));
            $user->setPrenom($facebookUser->getFirstName());
            $user->setNom($facebookUser->getLastName());
            $user->setEmail($facebookUser->getEmail());
            $user->setEnabled(true);
            $user->setSocialAuthentication(true);
        }
        $this->em->persist($user);
        $this->em->flush();


        return $user;
    }
 

Ответ №1:

У меня была такая же проблема, и я ссылался на токен доступа long live таким образом. Это может быть решением. Вот вы где.

 $client = $clientRegistry->getClient('facebook_main');
$accessToken = $client->getAccessToken();
if ($accessToken amp;amp; !$accessToken->getToken()) {
    dump("User is not found!"); die;
}
$provider = $client->getOAuth2Provider();
$longLivedToken = $provider->getLongLivedAccessToken($accessToken);
//I get the user by using long lived token
$facebookUser = $client->fetchUserFromToken($longLivedToken);
 

Комментарии:

1. Спасибо за ваш ответ. Я пробовал ваш код в контроллере Facebook, но я не использовал «$ facebookUser» в этом классе. Я поместил эту часть кода в connectCheckAction, это верно?

2. Он должен быть в классе FacebookAuthenticator. Насколько я помню.

3. Привет, Мерт, я поместил вашу часть кода в FacebookAuthenticator в метод getUser, который я ввел в свою правку 2, все еще не сработал, у меня то же сообщение. Спасибо за твою помощь, брат.

Ответ №2:

Первая ошибка, с которой вы столкнулись:

Ошибка при получении учетных данных OAuth: «Исключение OAuthException: использовался этот код авторизации»..

Это потому, что вы перезагружаете свою страницу (например, после изменения кода и обновления). В сообщении об ошибке говорилось, что код аутентификации в параметрах Url использовался ранее. Вместо этого обновите свой сайт 1. вернитесь на сайт, на котором размещена ваша кнопка, и 2. получите новый код авторизации, нажав кнопку входа в FB.

Теперь эта ошибка устранена, и вы можете перейти к отладке своего кода.