You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello,
I want to implement custom provider so users can log in / sign up with telegram in my Symfony 5.4 app. I do not want to use their widget.
The problem is that when a user accepts the login on the telegram auth url the window closes and I am not redirected back to my app for authentication.
Here is my code:
My TelegramProvider:
namespace App\Client;
use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Token\AccessToken;
use Psr\Http\Message\ResponseInterface;
class TelegramAuthProvider extends AbstractProvider
{
public function getBaseAuthorizationUrl()
{
return 'https://oauth.telegram.org/auth';
}
public function getBaseAccessTokenUrl(array $params)
{
return 'https://oauth.telegram.org/auth';
}
public function getResourceOwnerDetailsUrl(AccessToken $token)
{
return 'https://oauth.telegram.org/auth'. $token;
}
protected function getDefaultScopes()
{
return ['user_info'];
}
protected function checkResponse(ResponseInterface $response, $data)
{
if (empty($data['error'])) {
return;
}
}
protected function createResourceOwner(array $response, AccessToken $token)
{
return $response;
}
}
This is my telegram authenticator:
<?php
namespace App\Security;
use App\Entity\User;
// your user entity
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
use League\OAuth2\Client\Provider\GoogleUser;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\String\ByteString;
class TelegramAuthenticator extends OAuth2Authenticator implements AuthenticationEntrypointInterface
{
private ClientRegistry $clientRegistry;
private EntityManagerInterface $entityManager;
private RouterInterface $router;
private UserPasswordHasherInterface $hasher;
public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $entityManager, RouterInterface $router, UserPasswordHasherInterface $hasher)
{
$this->clientRegistry = $clientRegistry;
$this->entityManager = $entityManager;
$this->router = $router;
$this->hasher = $hasher;
}
public function supports(Request $request): ?bool
{
// continue ONLY if the current ROUTE matches the check ROUTE
return $request->attributes->get('_route') === 'connect_telegram_check';
}
public function authenticate(Request $request): Passport
{
$query = $request->query;
$telegramId = $request->query->get('id');
return new SelfValidatingPassport(
new UserBadge($telegramId, function () use ($telegramId, $query)
{
$userByTelegramId = $this->entityManager->getRepository(User::class)->findOneBy(['telegramId' => $telegramId]);
if ($userByTelegramId) return $userByTelegramId;
$user = new User();
$user->setTelegramId($telegramId);
$user->setFirstName($query->get('first_name'));
$user->setLastName($query->get('last_name'));
$user->setTelegramUsername($query->get('username'));
$randomString = ByteString::fromRandom(32)->toString();
$password = $this->hasher->hashPassword($user, $randomString);
$user->setPassword($password);
$this->entityManager->persist($user);
$this->entityManager->flush();
return $user;
})
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
$targetUrl = $this->router->generate('homepage');
return new RedirectResponse($targetUrl);
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
$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): Response
{
return new RedirectResponse(
'/login', // might be the site, where users choose their oauth provider
Response::HTTP_TEMPORARY_REDIRECT
);
}
}
TelegramController:
<?php
namespace App\Controller;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class TelegramController extends AbstractController
{
/**
* Link to this controller to start the "connect" process
*
* @Route("/connect/telegram", name="connect_telegram_start", options={"expose" : true})
*/
public function connectAction(ClientRegistry $clientRegistry, HttpClientInterface $client)
{
return $clientRegistry
->getClient('telegram')
->redirect([],[
'bot_id' => $this->getParameter('telegram_bot_id'),
'origin' => 'https://myapp.io',
'return_to' => 'https://myapp.io/register',
]);
// return new JsonResponse($url->getTargetUrl());
}
/**
* @Route("/connect/telegram/check", name="connect_telegram_check")
*/
public function connectCheckAction(Request $request, ClientRegistry $clientRegistry, EntityManagerInterface $entityManager)
{
}
}
knp config file:
knpu_oauth2_client:
clients:
# configure your clients as described here: https://github.com/knpuniversity/oauth2-client-bundle#configuration
facebook_main:
# this will be one of the supported types
type: facebook
client_id: '%env(OAUTH_FACEBOOK_ID)%'
client_secret: '%env(FACEBOOK_SECRET)%'
# the route that you're redirected to after
# see the controller example below
redirect_route: connect_facebook_check
redirect_params: {}
graph_api_version: v2.12
google:
# this will be one of the supported types
type: google
client_id: '%env(GOOGLE_CLIENT_ID)%'
client_secret: '%env(GOOGLE_SECRET)%'
# the route that you're redirected to after
# see the controller example below
redirect_route: connect_google_check
access_type: 'offline'
redirect_params: {}
telegram:
type: generic
provider_class: App\Client\TelegramAuthProvider
client_id: null
client_secret: '%env(TELEGRAM_TOKEN)%'
redirect_route: null
redirect_params: {}
Why am I not redirected back to my web app for authentication?
The text was updated successfully, but these errors were encountered:
The problem is that when a user accepts the login on the telegram auth url the window closes and I am not redirected back to my app for authentication.
Did you create any app / bot in the telegram for this? I suppose you need to check some configs there, probably you missed setting a redirect URL there? It's usually should be set up there.
Otherwise, please, check Telegram docs about how to redirect user back to your website.
Hello,
I want to implement custom provider so users can log in / sign up with telegram in my Symfony 5.4 app. I do not want to use their widget.
The problem is that when a user accepts the login on the telegram auth url the window closes and I am not redirected back to my app for authentication.
Here is my code:
My TelegramProvider:
This is my telegram authenticator:
TelegramController:
knp config file:
Why am I not redirected back to my web app for authentication?
The text was updated successfully, but these errors were encountered: