我找到了许多有关此问题的教程。但是没有人解决我的问题。因此,我正在尝试使用Symfony 4跟踪this tutorial来访问OAuth2 Facebook
当我单击“与Facebook建立联系”按钮时,我有一个空白页面,显示以下消息:
获取OAuth凭据时出错:“ OAuthException:此授权 代码已被使用。”。
我在一些教程中看到了有关accessToken,longliveAccessToken等的问题。
但是我不知道该怎么做才能解决此问题。
这是我的FacebookAuthenticator.php的代码:
<?php
namespace App\Security;
use App\Entity\User; // your user entity
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Security\Authenticator\SocialAuthenticator;
use KnpU\OAuth2ClientBundle\Client\Provider\FacebookClient;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
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!@#$%&*_";
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 && !$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!@#$%&*_";
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;
}
答案 0 :(得分:0)
我遇到了同样的问题,并且我已经通过这种方式引用了万用访问令牌。这可能是一个解决方案。你来了。
$client = $clientRegistry->getClient('facebook_main');
$accessToken = $client->getAccessToken();
if ($accessToken && !$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 :(得分:0)
您遇到的第一个错误:
获取OAuth凭据时出错:“ OAuthException:已使用此授权代码。”
那是因为您重新加载了页面(例如,在更改代码并刷新之后)。错误消息说以前在Url Params中使用了Auth Code。 而是刷新您的站点1.返回到放置按钮的站点,然后2.单击FB登录按钮获得新的身份验证代码。
现在此错误消失了,您可以继续调试代码了。