如何从早期/自动加载的Symfony 3路由器生成绝对URL [英] How to generate Absolute URL from Early/Auto loaded Symfony 3 router

查看:104
本文介绍了如何从早期/自动加载的Symfony 3路由器生成绝对URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写Guards来为我的Symfony 3应用程序处理OAuth。

I am writing Guards to handle OAuth for my Symfony 3 application.

作为其中一部分,在我的一项服务中,我需要生成一个绝对URL来

As part of it, in one of my services, I need to generate an absolute URL to send to Twitter as the Callback URL.

#services.yml
...
app.twitter_client:
    class: MyApiBundle\Services\TwitterClient
    arguments:
        - %twitter_client_id%
        - %twitter_client_secret%
        - connect_twitter_check
        - '@request_stack'
        - '@router'
        - '@logger'
app.twitter_authenticator:
    class: MyApiBundle\Security\TwitterAuthenticator
    arguments:
        - '@app.twitter_client'
        - '@logger'

记录器是临时的

#TwitterClient.php service
...
use Monolog\Logger;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\RouterInterface;
class TwitterClient
{

/**
 * TwitterClient constructor.
 * @param string          $identifier
 * @param string          $secret
 * @param string          $callbackUrl
 * @param RequestStack    $requestStack
 * @param RouterInterface $router
 * @param Logger          $logger
 */
public function __construct(
    string $identifier,
    string $secret,
    string $callbackUrl,
    RequestStack $requestStack,
    RouterInterface $router,
    Logger $logger
) {
    $callbackUrl = $router->generate($callbackUrl, [], RouterInterface::ABSOLUTE_URL);
    $logger->info($callbackUrl);
    ...
}

当它输出 $ callbackUrl 到日志,它只是说本地主机,即使我使用其他URL访问它。

And when it outputs the $callbackUrl to the logs, it just says localhost, even though I am accessing it using a different URL.

http://localhost/connect/twitter/check

但是如果我这样做了

#TwitterController.php
...
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;


class TwitterController extends Controller
{
    /**
     * @Route("/connect/twitter")
     * @return RedirectResponse
     */
    public function connectAction()
    {
        /** @var RouterInterface $router */
        $router = $this->container->get('router');
        $callbackUrl = $router->generate('connect_twitter_check', [], RouterInterface::ABSOLUTE_URL);
        /** @var Logger $logger */
        $logger = $this->container->get('logger');
        $this->container->get('logger')
            ->info($callbackUrl);
        ...

输出结果:

https://dev.myapi.com:8082/app_dev.php/connect/twitter/check

在我的hosts文件中设置了 dev.myapi.com 域,并指向localhost,以便于

The dev.myapi.com domain is set up in my hosts file and points to localhost, to make it easier to differentiate between my local apps and also to make it easier to integrate with OAuth services.

推荐答案

我设法通过设置以下内容来解决此问题:路由器上下文。
我已经加载到RequestStack中以访问用户的IP,所以我用它来设置Route的上下文,然后路由器按预期工作。
我遇到了问题,试图在其中使用RequestStack构造函数,所以我最终对其进行了重构,以便它尽可能晚地使用RequestStack。

I managed to solve this by setting the Router context. I already loaded in the RequestStack to access the user's IP, so I used it to set the context of the Route and then the router worked as expected. I ran into problems trying to use the RequestStack in the constructor, so I ended up refactoring it so that it used the RequestStack as late as possible.

class TwitterClient
{
    private $identifier;
    private $secret;
    private $callbackUrl;
    private $requestStack;
    private $router;
    private $server;

    /**
     * TwitterClient constructor.
     *
     * @param string          $identifier
     * @param string          $secret
     * @param string          $callbackUrl
     * @param RequestStack    $requestStack
     * @param RouterInterface $router
     */
    public function __construct(
        string $identifier,
        string $secret,
        string $callbackUrl,
        RequestStack $requestStack,
        RouterInterface $router
    ) {
        $this->identifier = $identifier;
        $this->secret = $secret;
        $this->callbackUrl = $callbackUrl;
        $this->requestStack = $requestStack;
        $this->router = $router;
    }

    /**
     * Wait until the last moment to create the Twitter object to make sure that the requestStack is loaded.
     *
     * @return \League\OAuth1\Client\Server\Twitter
     */
    private function getServer()
    {
        if (!$this->server) {
            $context = new RequestContext();
            $context->fromRequest($this->requestStack->getCurrentRequest());
            $this->router->setContext($context);
            $callbackUrl = $this->router->generate($this->callbackUrl, [], RouterInterface::ABSOLUTE_URL);
            $this->server = new Twitter(
                [
                    'identifier' => $this->identifier,
                    'secret' => $this->secret,
                    'callback_uri' => $callbackUrl,
                ]
            );
        }

        return $this->server;
    }
    ...
}

这篇关于如何从早期/自动加载的Symfony 3路由器生成绝对URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆