#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.
Теперь эта ошибка устранена, и вы можете перейти к отладке своего кода.