laravel - guzzle post 請求 登入 api, response回傳 404,錯在哪裡呢?
女神的闺蜜爱上我
女神的闺蜜爱上我 2017-06-13 09:24:33
0
1
1565

筆者的guzzle程式碼是這樣的:

use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\RequestException;

class getSegmentfaultArticle extends Command
{
    protected $signature = 'segmentfault:artical';

    protected $description = '获取 Segmentfault 文章的信息';

    protected $client;
    protected $crawler;

    protected $user = [];

    protected $login_page_url = '/user/login';
    protected $login_url = '/api/user/login?_=775250c435a29c7a335a11ab2f641423';
    protected $sessionId = 'web2~04u8m9qfpnt6abl6ljuqae59l0';
    protected $my_seg_home_url = '/u/greenlightt/articles';

    public function __construct(Crawler $crawler) {
        parent::__construct();

        $this->client  = new Client([
            'base_uri' => 'https://segmentfault.com',
            'headers' => [
                'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0',
                 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
            ],
            'cookies' => true,
            'http_errors' => true,
        ]);
        $this->crawler = $crawler;

        // 获取登录名及密码
        $this->user['email'] = config('services.segmentfault.email');
        $this->user['password'] = config('services.segmentfault.password');
    }

    public function handle() {
        // 较验 auth
        if (is_null($this->user['email']) || is_null($this->user['password'])) {
            $this->error('请在 .env 文件填写 Segmentfault 账号及密码');
            return;
        }
        // 登录获取 cookies
        $this->client->request('GET', $this->login_page_url);
        $this->updateCookies();
        
        $response = $this->client->request('POST', $this->login_url,
            array(
                'form_params' => [
                    'username' => $this->user['email'],
                    'password' => $this->user['password'],
                ],
                'headers' => [
                    'Referer' => '/user/login'
                ]
            )
        );
    }
    
    /*                                                                          
     * 修改 Cookie 中的 PHPSESSID 值                                            
     */                                                                         
     protected function updateCookies() {                                        
        $config = $this->client->getConfig();                                   
        $cookie = $config['cookies']->toArray()[0];                             
        $cookie['Value'] = $this->sessionId;                                    
                                                                                    
        $config['cookies']->setCookie(                                          
           new SetCookie($cookie)                                              
        );                                                                      
     }   
}

結果報錯如下:

#
女神的闺蜜爱上我
女神的闺蜜爱上我

全部回覆(1)
三叔

login?_=後面的token不是固定的,你要手動從window.SF.token裡面取出來。

另外請求的時候cookie也沒有帶,所以SF判斷你是非法請求,404.

鑑於樓主認為_後面的token屬於隨意的字段,下面來驗證一下,以下給出運行正確的代碼(沒有用laravel)

因為SF的token有混淆字段,php應該不能簡單的解析出來,所以直接用shell_exe呼叫node來取得token。

<?php
require_once __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\RequestException;

$login_page_url = '/user/login';
$login_url = '/api/user/login?_=';

$client = new Client([
    'base_uri' => 'https://segmentfault.com',
    'headers' => [
        'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0',
        'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
    ],
    'cookies' => true,
    'http_errors' => true,
]);

$user = [
    'email' => '1@qq.com',
    'password' => '2333',
];

$response = $client->request('GET', $login_page_url);
$body = (string) $response->getBody();
preg_match_all('/<script[\s\S]*?<\/script>/', $body, $matches);
$script = null;
foreach ($matches[0] as $value) {
    if (strpos($value, 'w.SF.token') !== false) {
        $script = $value;
        break;
    }
}
$script = str_replace(['<script>', '</script>'], '', $script);
file_put_contents(__DIR__ . '/test.js', 'var window = {};' . "\r\n" . $script . "\r\n" . 'console.log(window.SF.token);');
$token = shell_exec('/usr/local/bin/node test.js' . " 2>&1");
$token = trim($token);

// get cookie
$config = $client->getConfig();
$cookie = $config['cookies']->toArray()[0];

$cookieJar = CookieJar::fromArray([
    $cookie['Name'] => $cookie['Value'],
], $cookie['Domain']);

try {
    $response = $client->request('POST', $login_url . $token,
        array(
            'cookies' => $cookieJar,
            'form_params' => [
                'username' => $user['email'],
                'password' => $user['password'],
            ],
            'headers' => [
                'Referer' => '/user/login',
            ],
        )
    );
} catch (RequestException $e) {
    echo $e->getMessage();
}

echo (string) $response->getBody();

輸出結果:

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!