GuzzleHttp:如何从 POST 响应中保存 cookie 并在下一个 POST 中使用它?

Posted

技术标签:

【中文标题】GuzzleHttp:如何从 POST 响应中保存 cookie 并在下一个 POST 中使用它?【英文标题】:GuzzleHttp:how can I save cookies from a POST response and use it in the next POST? 【发布时间】:2018-01-06 11:54:34 【问题描述】:

我正在使用 Guzzle 登录我的 API 站点,当我使用正确的凭据登录时,我会返回一个带有 RefreshToken 的 cookie,以便在下一次调用中发送它,这是我的简单(并且运行良好)代码:

$client = new Client(array(
            'cookies' => true
        ));


        $response = $client->request('POST', 'http://myapi.com/login', [
            'timeout' => 30,
            'form_params' => [
                'email' => $request->get('email'),
                'password' => $request->get('password'),
            ]
        ]);

我用 cookie 得到正确的响应,我可以通过以下方式查看 cookie:

$newCookies = $response->getHeader('set-cookie');

现在,我需要在下一次调用中使用这个 cookie,我知道 Guzzle 可以为我保存 cookie,并在下一次调用中使用“CookieJar”或“SessionCookieJar”自动发送(或不发送),我有尝试使用它,但我没有看到 'jar' 中的 cookie,这是我所做的:

$cookieJar = new SessionCookieJar('SESSION_STORAGE', true);

        $client = new Client([
          'cookies' => $cookieJar
        ]);

        $response = $client->request ....

但是,当我从 POST 中取回 cookie 时,我只能通过以下方式看到它:

$newCookies = $response->getHeader('set-cookie');

它不在 cookieJar 中,所以它不会在下一次调用中发送它.. 我在这里错过了什么?

谢谢!

【问题讨论】:

docs.guzzlephp.org/en/stable/quickstart.html#cookies。您需要为登录请求设置 jar 以便它收集 cookie 感谢您的回答,我已经尝试在请求中设置它并且在新客户端初始化中没有任何效果(我已经阅读了很多次手册),您可以添加一些代码吗?跨度> 【参考方案1】:
//post form params    
$response = $client->post( '/login', [
        'form_params' => [
            'login' => 'login',
            'password => 'password',
        ],
        'headers' => [
            'Accept' => 'text/html,application/xhtml+xm…ml;q=0.9,image/webp,*/*;q=0.8',
            'Content-Type' => 'application/x-www-form-urlencoded',
            'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0'
        ]
    ]);

//get cookie from header in response
$cookie = $response->getHeaderLine('Set-Cookie');

//get page with cookie
$client->get('/products', [
        'headers' => [
            'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36',
            'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
            'accept-encoding' => 'gzip, deflate, br',
            'accept-language' => 'ru',
            'cookie' => $cookie, //this cookie data
        ],
        'debug' => false
    ]);

【讨论】:

您好,感谢您的回答。如果你能解释你的代码是做什么的,那就太好了。以这种方式向您学习将有助于社区更多!【参考方案2】:

根据文档here,['cookies' => true] 表示对所有请求使用共享 cookie jar,而 ['cookies' => $jar] 表示使用特定 cookie jar ($jar ) 用于客户的请求/响应。所以你需要使用:

$client = new Client(array(
    'cookies' => true
));


$response = $client->request('POST', 'http://myapi.com/login', [
    'timeout' => 30,
    'form_params' => [
        'email' => $request->get('email'),
        'password' => $request->get('password'),
    ]
]);

// and using the same client

$response = $client->request('GET', 'http://myapi.com/next-url');

// or elsewhere ...

$client = new Client(array(
    'cookies' => true
));

$response = $client->request('GET', 'http://myapi.com/next-url');

$jar = new CookieJar;

$client = new Client(array(
    'cookies' => $jar
));


$response = $client->request('POST', 'http://myapi.com/login', [
    'timeout' => 30,
    'form_params' => [
        'email' => $request->get('email'),
        'password' => $request->get('password'),
    ]
]);

// and using the same client

$response = $client->request('GET', 'http://myapi.com/next-url');

// or elsewhere ...

$client = new Client(array(
    'cookies' => $jar // the same $jar as above
));

$response = $client->request('GET', 'http://myapi.com/another-url');

【讨论】:

以上是关于GuzzleHttp:如何从 POST 响应中保存 cookie 并在下一个 POST 中使用它?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel + GuzzleHTTP 没有响应数据?

guzzlehttp/guzzle

在 laravel 中使用 GuzzleHttp 发送原始空 json

Laravel 8/Passport/GuzzleHttp APO 返回 200 OK 但没有正文响应

如何将 parseJSON 响应保存到数组

如何使用 Django 从 POST 表单中获取 JSON 响应