如何使用 curl 函数 模拟登录 Laravel 自带的 auth?

遇到一个爬虫模拟登录的问题。使用curl登录laravel自带的auth的时候csrf_token也带上了,但是还是返回419....这是为什么呢?

        $cookie= __DIR__.'/cookie.txt';
        $url = 'https://xxx.com';
        $headers = [
            'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
            'Content-Type: application/x-www-form-urlencoded; charset=utf-8',
            'Cache-Control: max-age=0',
            'upgrade-insecure-requests: 1',
        ];
        $post = [
            'email' => '123@123.com',
            'password' => '123xxx',
            '_token' => 'xxxx',  //这边的token值是在浏览器元素中找到的token值.为了防止token过期,刷新过
        ];
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, $headers);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
        curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
        $content = curl_exec($curl);
        curl_close($curl);

返回的$content:

HTTP/2 419 
server: nginx
content-type: text/html; charset=UTF-8
cache-control: no-cache, private
date: Fri, 28 Jun 2019 10:34:13 GMT
set-cookie: _session=xxxxxx %3D%3D; expires=Fri, 28-Jun-2019 16:34:13 GMT; Max-Age=21600; path=/; httponly

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Page Expired</title>

        <!-- Fonts -->
        <link rel="dns-prefetch" href="//fonts.gstatic.com">
        <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

        <!-- Styles -->
        <style>
            html, body {
                background-color: #fff;
                color: #636b6f;
                font-family: 'Nunito', sans-serif;
                font-weight: 100;
                height: 100vh;
                margin: 0;
            }

            .full-height {
                height: 100vh;
            }

            .flex-center {
                align-items: center;
                display: flex;
                justify-content: center;
            }

            .position-ref {
                position: relative;
            }

            .code {
                border-right: 2px solid;
                font-size: 26px;
                padding: 0 15px 0 15px;
                text-align: center;
            }

            .message {
                font-size: 18px;
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div class="flex-center position-ref full-height">
            <div class="code">
                419            </div>

            <div class="message" style="padding: 10px;">
                Page Expired            </div>
        </div>
    </body>
</html>

文中的一些敏感信息使用xxxx代替

面向Google编程
drinke9
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
Raymond3689
最佳答案

1.以下代码测试可行

<?php
$url = 'http://homestead.test/login/';

$data = [
    '_token'=>"miZ6so4z0Fnu2qsPP4GxO1rJkIIDgo8F3jIg2yl0",
    'email'=>'runxindong@gmail.com',
    'password'=>'xxxxx',
];
$data = http_build_query($data);
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
// curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);

$header = [
    "Connection: keep-alive",
    "Content-Type: application/x-www-form-urlencoded",
    // "Content-Length: " . strlen($data),
    "Host: homestead.test",
    // "Origin: http://homestead.test",
    "Referer: http://homestead.test/login",
    "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
    "Upgrade-Insecure-Requests: 1",
    "Cookie: XSRF-TOKEN=eyJpdiI6InBmQWhTeGF6cjRXK3k0ZEdWNFNOXC93PT0iLCJ2YWx1ZSI6Ikp4am1oNHVWWmRnbFg1OUJcLzNrd3hTTWJxbXQyaG9qdnZjRVwvZ0Y3aHJ2WFV4TjdPM0k3MVFhUVl6RW55Wk9ReiIsIm1hYyI6IjE4ZWQyOGIyNTYzNDdkZDY0MDMyMjJlOGJhNjNmZjY0MmU4MGE2MmE3MjJkZDg5MmM0ZGVkMjg5YWQzZjk5YmQifQ%3D%3D; laravel_session=eyJpdiI6Ik5icTRhUzZQTDl4SVhWd05tMGUxaEE9PSIsInZhbHVlIjoiQ2RQa0U1NW5yWE9aYWFIQUQ3cjc2ZTNyXC80dURxQnJEUnIrZ0ZYQUNWTG9Qb0lRcFFxYlAzNlgwZlZPdGorM0IiLCJtYWMiOiIzYjk1N2ZiYmI0MzgwMDRhMzUzNTM5OTMwNjU3M2E0OWJjYzE1YWQ4NGVjYmE2Y2IwOTZjMzcyMTNlNjBiZGYzIn0%3D"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
if($output === false){
    echo "cURL Error: " . curl_error($ch);
}

curl_close($ch);

echo $output;

2.分析

1)注意 curl option CURLOPT_HEADER(启用时将头文件的信息作为数据流输出) 和 CURLOPT_HTTPHEADER(用来设置HTTP头字段的数组)的区别

2)将cookie放在HTTP头部

$header = [
    .
    .
    "Cookie: XSRF-TOKEN=eyJpdiI6InBmQWhTeGF6cjRXK3k0ZEdWNFNOXC93PT0iLCJ2YWx1ZSI6Ikp4am1oNHVWWmRnbFg1OUJcLzNrd3hTTWJxbXQyaG9qdnZjRVwvZ0Y3aHJ2WFV4TjdPM0k3MVFhUVl6RW55Wk9ReiIsIm1hYyI6IjE4ZWQyOGIyNTYzNDdkZDY0MDMyMjJlOGJhNjNmZjY0MmU4MGE2MmE3MjJkZDg5MmM0ZGVkMjg5YWQzZjk5YmQifQ%3D%3D; laravel_session=eyJpdiI6Ik5icTRhUzZQTDl4SVhWd05tMGUxaEE9PSIsInZhbHVlIjoiQ2RQa0U1NW5yWE9aYWFIQUQ3cjc2ZTNyXC80dURxQnJEUnIrZ0ZYQUNWTG9Qb0lRcFFxYlAzNlgwZlZPdGorM0IiLCJtYWMiOiIzYjk1N2ZiYmI0MzgwMDRhMzUzNTM5OTMwNjU3M2E0OWJjYzE1YWQ4NGVjYmE2Y2IwOTZjMzcyMTNlNjBiZGYzIn0%3D"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
4年前 评论
oidns 4年前
夜游人 2年前
夜游人 2年前
讨论数量: 15

请求要附带 CSRF token ,,,

4年前 评论
drinke9 (楼主) 4年前

用API不就不需要token了么?

4年前 评论
drinke9 (楼主) 4年前
leo

需要同时带上 cookie 才行

4年前 评论
leo (作者) 4年前
drinke9 (楼主) 4年前
Raymond3689

1.以下代码测试可行

<?php
$url = 'http://homestead.test/login/';

$data = [
    '_token'=>"miZ6so4z0Fnu2qsPP4GxO1rJkIIDgo8F3jIg2yl0",
    'email'=>'runxindong@gmail.com',
    'password'=>'xxxxx',
];
$data = http_build_query($data);
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
// curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);

$header = [
    "Connection: keep-alive",
    "Content-Type: application/x-www-form-urlencoded",
    // "Content-Length: " . strlen($data),
    "Host: homestead.test",
    // "Origin: http://homestead.test",
    "Referer: http://homestead.test/login",
    "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
    "Upgrade-Insecure-Requests: 1",
    "Cookie: XSRF-TOKEN=eyJpdiI6InBmQWhTeGF6cjRXK3k0ZEdWNFNOXC93PT0iLCJ2YWx1ZSI6Ikp4am1oNHVWWmRnbFg1OUJcLzNrd3hTTWJxbXQyaG9qdnZjRVwvZ0Y3aHJ2WFV4TjdPM0k3MVFhUVl6RW55Wk9ReiIsIm1hYyI6IjE4ZWQyOGIyNTYzNDdkZDY0MDMyMjJlOGJhNjNmZjY0MmU4MGE2MmE3MjJkZDg5MmM0ZGVkMjg5YWQzZjk5YmQifQ%3D%3D; laravel_session=eyJpdiI6Ik5icTRhUzZQTDl4SVhWd05tMGUxaEE9PSIsInZhbHVlIjoiQ2RQa0U1NW5yWE9aYWFIQUQ3cjc2ZTNyXC80dURxQnJEUnIrZ0ZYQUNWTG9Qb0lRcFFxYlAzNlgwZlZPdGorM0IiLCJtYWMiOiIzYjk1N2ZiYmI0MzgwMDRhMzUzNTM5OTMwNjU3M2E0OWJjYzE1YWQ4NGVjYmE2Y2IwOTZjMzcyMTNlNjBiZGYzIn0%3D"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
if($output === false){
    echo "cURL Error: " . curl_error($ch);
}

curl_close($ch);

echo $output;

2.分析

1)注意 curl option CURLOPT_HEADER(启用时将头文件的信息作为数据流输出) 和 CURLOPT_HTTPHEADER(用来设置HTTP头字段的数组)的区别

2)将cookie放在HTTP头部

$header = [
    .
    .
    "Cookie: XSRF-TOKEN=eyJpdiI6InBmQWhTeGF6cjRXK3k0ZEdWNFNOXC93PT0iLCJ2YWx1ZSI6Ikp4am1oNHVWWmRnbFg1OUJcLzNrd3hTTWJxbXQyaG9qdnZjRVwvZ0Y3aHJ2WFV4TjdPM0k3MVFhUVl6RW55Wk9ReiIsIm1hYyI6IjE4ZWQyOGIyNTYzNDdkZDY0MDMyMjJlOGJhNjNmZjY0MmU4MGE2MmE3MjJkZDg5MmM0ZGVkMjg5YWQzZjk5YmQifQ%3D%3D; laravel_session=eyJpdiI6Ik5icTRhUzZQTDl4SVhWd05tMGUxaEE9PSIsInZhbHVlIjoiQ2RQa0U1NW5yWE9aYWFIQUQ3cjc2ZTNyXC80dURxQnJEUnIrZ0ZYQUNWTG9Qb0lRcFFxYlAzNlgwZlZPdGorM0IiLCJtYWMiOiIzYjk1N2ZiYmI0MzgwMDRhMzUzNTM5OTMwNjU3M2E0OWJjYzE1YWQ4NGVjYmE2Y2IwOTZjMzcyMTNlNjBiZGYzIn0%3D"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
4年前 评论
oidns 4年前
夜游人 2年前
夜游人 2年前

露个脸 :grin:

4年前 评论
drinke9 (楼主) 4年前
drinke9

@rundong 感谢回复

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!