当前位置: 首页 > 知识库问答 >
问题:

Symfony 4.3 PHP:如何从302重定向响应中读取cookie?

顾正初
2023-03-14

我想做什么(在控制器中)

  1. 接收请求,根据该请求
  2. 发送外部HTTP请求
  3. 解析响应,并基于此
  4. 回复

我计划有多个函数都遵循这个模式。他们一个接一个地被召唤。

Symfony 4.3引入了HttpClient组件和BrowserKit组件,乍一看似乎符合要求。但事实证明,事情变得更加复杂。外部HTTP请求被发送到一个服务器,该服务器使用cookie跟踪会话,这应该不会太不寻常。如果发送请求时没有cookie,服务器总是使用相同的登录页内容进行响应。所以我们需要饼干。不用担心,对初始请求的响应带有一个“Set Cookie”头,其中包含在后续请求的“Cookie”头中发送的Cookie。带有cookie的响应的HTTP状态为“302 Found”,在正常的web环境中,它使用web浏览器重定向到请求中具有相同cookie的下一页。在我的Symfony控制器中复制此操作似乎非常棘手。展开第2步。我现在想做什么:

2.a。发送外部HTTP请求

2.b。从302响应中读取cookie(没有自动重定向)

2.c。设置后续请求的“Cookie”头,该值来自2。B

2. d.将请求发送到新目标(在302响应的“位置”标头中设置)

以下是来自控制器的一些代码:

use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\Exception\RedirectionException;
use Symfony\Component\HttpFoundation\JsonResponse;

public function init(Request $request): JsonResponse
{
    $url = "external url";
    $client = HttpClient::create();
    try {
        $response = $client->request('GET', $url, [
            'max_redirects' => -1
        ]);
    } catch (RedirectionException $redirectionException) {

    }
    return new JsonResponse([], 200);
}

不设置max_redirects意味着客户端遵循重定向,最终返回200响应而没有任何cookie。将值设置为-1将引发重定向异常,并且再次,带有cookie的302响应似乎丢失了。

我还尝试了HttpBrowser组件:

$cookieJar = new CookieJar();
$client = new HttpBrowser(HttpClient::create(), null, $cookieJar);
$client->request('GET', $url);

但是我得到一个200响应没有cookie,因为它自动跟随重定向。

我知道这里提到的组件是Symfony 4.3和“实验性”的新组件,但我也不认为我的任务过于复杂或不寻常。但是也许Symfony还有其他超文本传输协议客户端更适合这项任务?

共有1个答案

方风华
2023-03-14

事实证明,通过尝试Symfony的其他HTTP客户端组件比本机组件更容易完成此任务。所以我暂时把Symfony HttpClient和HttpBrowser放在一边。我设法用guzzle HTTP/guzzle版本6.3实现了这个问题的解决方案。3.以下是我的控制器功能的外观:

use GuzzleHttp\Client;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

public function init(Request $request): JsonResponse {
    $client = new Client([
        'base_uri' => 'an external domain',
        'cookies' => true
    ]);
    // get the 302 response, without following
    $response = $client->get('path',[
        'allow_redirects' => false
    ]);
    // get the cookie from the 302 response
    $jar = new \GuzzleHttp\Cookie\CookieJar(true,[$response->getHeader('Set-Cookie')]);
    // follow the redirect manually, with the cookie from the 302 response
    $redirectResponse = $client->request('GET', $response->getHeader('Location')[0], [
        'cookies' => $jar
    ]);

    $jsonResponse = new JsonResponse(['message' => 'my message'],200);
    $originalCookie = Cookie::fromString($response->getHeader('Set-Cookie')[0]);
    $newCookie = Cookie::create(
        $originalCookie->getName(),
        $originalCookie->getValue(),
        $originalCookie->getExpiresTime(),
        '/',
        'my domain',
        false,
        true,
        $originalCookie->isRaw(),
        $originalCookie->getSameSite()
    );

    $jsonResponse->headers->setCookie($newCookie);
    return $jsonResponse;
}

不能从响应中获取cookie,否则它将永远不会被发回,因为域或路径不匹配。所以我创建了一个与原始cookie非常相似的新cookie,然后将其发送回浏览器。这样,cookie在随后的请求中返回,数据内容可以向前发送。

这里出现的其他问题是必须在外部服务器上处理的同源性要求。

我仍然对如何使用本地Symfony 4.3组件完成这一切感兴趣,或者,如果有人能确认这是不可能的。

 类似资料:
  • 我在我的应用程序上安装了一个服务工作者,它安装得很好,激活得很好,缓存也可以。 但当我点击302页面时,缓存完成后,它会告诉我: http://localhost:8000/form/的Fetch事件导致网络错误响应:重定向响应用于重定向模式不是“跟随”的请求。 我已经读了很多关于这个主题的文章,我在这里查阅了一些帖子:服务人员破坏301重定向,还有那里https://github.com/w3c

  • 我创建了一个反向代理,如下所示: 并从main调用它: 它在客户端可以正常工作,但是我想阅读代理的响应,我怎么做?

  • 问题内容: 我要访问一个首先需要(tomcat服务器)身份验证的站点,然后使用POST请求登录,并保留该用户以查看站点的页面。我使用Httpclient 4.0.1 第一次身份验证可以正常运行,但登录时始终不会抱怨此错误:“ 302临时移动” 我保留cookie并保留上下文,但是什么也没有。实际上,登录似乎可行,因为如果我输入了错误的参数或用户||密码,则会看到登录页面。所以我想自动重定向是行不通

  • 问题内容: 我有两个Python脚本。一种使用Urllib2库,另一种使用Requests库。 我发现请求更容易实现,但是找不到urlib2的等效函数。例如: 建立完发布网址后,请给我内容-我正尝试连接到vcloud Director api实例,并且响应显示了我有权访问的端点。但是,如果我按以下方式使用请求库.... .... the和不返回任何内容,即使请求后调用中的状态代码等于200。 为什

  • 问题内容: 我正在使用RestTemplate.postForObject将信息发布到Web服务。除了结果字符串,我还需要响应头中的信息。有什么办法可以做到这一点? 问题答案: 好吧,我终于明白了。交换方法正是我所需要的。它返回包含完整标头的HttpEntity。

  • 我正在尝试使用SpringREST模板进行post请求以登录。 我的ResponseEntity状态是302,我想按照此请求获取正文响应,因为我没有获取此请求的正文。 我能做些什么来解决这个问题?!