Помогите залогиниться через cURL на своем же сайте

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
webgrig
Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Помогите залогиниться через cURL на своем же сайте

Сообщение webgrig »

Пытаюсь сделать так:

Код: Выделить всё

function login($url, $login, $pass){
    $cookie = dirname(__DIR__).'\grab\cookie.txt';
    $ch = curl_init();
    if(strtolower((substr($url,0,5))=='https')) { // если соединяемся с https
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    }
    curl_setopt($ch, CURLOPT_URL, $url);
    // откуда пришли на эту страницу
    curl_setopt($ch, CURLOPT_REFERER, $url);
    // cURL будет выводить подробные сообщения о всех производимых действиях
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,"LoginForm[username]=".$login."&LoginForm[password]=".$pass
    ."&LoginForm[rememberMe]=1&"
    . Yii::$app->getRequest()->csrfParam . "=".Yii::$app->getRequest()->getCsrfToken(''));
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (Windows; U; Windows NT 5.0; En; rv:1.8.0.2)
    Gecko/20070306 Firefox/1.0.0.4");
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    //сохранять полученные COOKIE в файл
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
    $result=curl_exec($ch);
    curl_close($ch);
    return $result;
}
echo login('http://site.loc/manager/sign-in/login', 'manager', 'test');
cURL возвращает вот такие заголовки
HTTP/1.1 400 Bad Request
Date: Mon, 18 Dec 2017 13:02:05 GMT
Server: Apache
Set-Cookie: PHPSESSID=kh6lpv8rv10sqqnb4rnik57k82; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: max-age=0, private, no-store, no-cache, must-revalidate, no-transform
Pragma: no-cache
X-Debug-Tag: 5a37bc4dc2897
X-Debug-Duration: 1,273
X-Debug-Link: /manager/debug/default/view?tag=5a37bc4dc2897
Set-Cookie: _csrf=5f3067fd49aca010e0dda5daa8cd331835a9639fb78c025b01c14bb08334f723a%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%228joOMjiyDN5wG4yEwwe0b6TXBH7RKXz2%22%3B%7D; path=/; HttpOnly
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
ну и на страничке авторизации выдается сообщение:

Код: Выделить всё

Ошибка 400
Не удалось проверить переданные данные.
Подскажите, что не так.
Почему авторизация не проходит?
Последний раз редактировалось webgrig 2017.12.19, 00:29, всего редактировалось 2 раза.
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: Помогите залогиниться через cURL

Сообщение urichalex »

csrf полагаю
webgrig
Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Помогите залогиниться через cURL на своем же сайте

Сообщение webgrig »

urichalex писал(а): 2017.12.18, 17:30 csrf полагаю
A что с ним не так? На сервер он передается, я проверял в дебаге.
Последний раз редактировалось webgrig 2017.12.19, 00:30, всего редактировалось 1 раз.
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: Помогите залогиниться через cURL

Сообщение urichalex »

Вы курлом со своего же сайта берете чтоли?
webgrig
Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Помогите залогиниться через cURL на своем же сайте

Сообщение webgrig »

urichalex писал(а): 2017.12.18, 20:34 Вы курлом со своего же сайта берете чтоли?
Я делаю синхронизатор новостей, с другим моим сайтом сделанном на ModX.

Через cUrl я получил контент, получил картинки, теперь хочу в цикле создавать новые модели новостей и сохранять их в базе.

Но предварительно, у меня должны сохранится картинки!

Для этого я должен курлом обратиться к своему же контроллеру на бекенде http://site.loc/manager/file-storage/upload
А так как для обращения к бекенду нужна авторизация, то вот я и пытаюсь сначала залогиниться,
а потом уже передавать файлы, сохранять модели и т.д.

Но логин не проходит, и пока я не могу понять в чем дело.
someweb
Сообщения: 552
Зарегистрирован: 2017.03.09, 10:12

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение someweb »

Зачем для своего сайта такие сложности?
Сделайте, например, через Bearer.
Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа. Роберт Шекли.
webgrig
Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение webgrig »

someweb писал(а): 2017.12.19, 09:21 Зачем для своего сайта такие сложности?
Сделайте, например, через Bearer.
Сори, я не понимаю о чем речь.
Можно хоть в двух словах объяснить, что такое Bearer и с чем его едят.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение Loveorigami »

Буквально, сегодня делал через Guzzle

Код: Выделить всё


    /**
     * @param $url
     * @return mixed|\Psr\Http\Message\ResponseInterface
     */
    protected function getRequest($url)
    {
        /** @var \GuzzleHttp\Client $client */
        $client = $this->getClient();

        //manually create the cookie jar
        $cookieFile = $this->getFolder('/') . date('Y-m-d_') . 'jar.txt';
        $cookieJar = new FileCookieJar($cookieFile, true);

        if (!file_exists($cookieFile)) {
            $client->request('POST', '/ucp.php?mode=login', [
                'form_params' => [
                    'username' => '***',//post a field named 'username',
                    'password' => '***',//post a field named 'password',
                ],
                'cookies' => $cookieJar,
                'debug' => true
            ]);
        }

        $response = $client->request('GET', $url, [
            'cookies' => $cookieJar,
        ]);

        return $response;
    }
someweb
Сообщения: 552
Зарегистрирован: 2017.03.09, 10:12

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение someweb »

Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа. Роберт Шекли.
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение urichalex »

Скажите, для чего с одного и того же сайта получать данные пост запросом?
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение mkramer »

http://site.loc/manager/file-storage/upload - вынесете отсюда код обработки файлов в отдельный класс, и дёргайте его и там и там, не занимайтесь фигнёй. А проблема, скорее всего, в CSRF, поскольку в сессии его нету, когда вы курлом обращаетесь к нему (ведь при обращении курлом сессия другая создаётся). Т.е. по идее, вам надо сначала обратиться get-запросом, вытянуть из нужной формы csrf, сохранить куки, и только потом с этими куками и csrf-ом лезть с post-запросом. Но это как ногу через голову чесать для вашей задачи.
webgrig
Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение webgrig »

someweb писал(а): 2017.12.19, 09:21 Сделайте, например, через Bearer.
Я прошу прощения, за некомпетентность, но я бы хотел побольше узнать об этом, где можно посмотреть как использовать HTTP Bearer Tokens.
пока я нашел только официальную документацию
http://www.yiiframework.com/doc-2.0/yii ... rauth.html
но мне не понятно как получить токен, как его отправить на сервер, какие настройки нужно сделать в конфигурации что бы использовать класс yii\filters\auth\HttpBearerAuth, и т.д.

В общем я бы хотел разобраться с этим, и мне нужны примеры реализации.
Подскажите пож. где можно об этом почитать, желательно на русском (но не обязательно).
Спасибо.
webgrig
Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение webgrig »

ElisDN писал(а): 2017.12.21, 11:05 http://www.elisdn.ru/blog/103/yii2-rest-api
Спасибо, очень классный урок!
Но у меня возникла проблема, прошу вашей помощи.
=============
Но перед тем как я опишу суть проблемы, я хотел бы вам сказать, что на гитхабе в вашем проекте нужно поправить composer.json
вместо вот этого:

Код: Выделить всё


    "extra": {
        "asset-installer-paths": {
            "npm-asset-library": "vendor/npm",
            "bower-asset-library": "vendor/bower"
        }
    },
нужно написать вот это:

Код: Выделить всё

    "repositories": [
      {
          "type": "composer",
          "url": "https://asset-packagist.org"
      }
    ],
иначе после composer install возникает ошибка.

Но да ладно это так, лирическое отступление.

===============================

А проблема собственно вот в чем.
Дело в том, что в вашем примере используется advenset шаблон, при котором для разделов frontend, backend и api настроены отдельные домены, а мне нужно реализовать api интерфейс на сайте где все эти разделы будут на одном домене.

Поэтому, я создал на локальном сервере новый тестовый проект, склонировал ваш репозетарий с примером и попытался настроить его для работы с одним доменом.

Так как у меня на боевом сайте, где нужно реализовать api, есть .htaccess в котором прописаны правила маршрутизации для frontend и backend, то я добавил его также и в новый локальный проект с вашим примером, только дописал правила для папки api: получилось вот так:

Код: Выделить всё

RewriteCond %{REQUEST_URI} ^/manager
RewriteRule ^manager(.*) /backend/web/$1 [L]

RewriteCond %{REQUEST_URI} ^/api
RewriteRule ^api(.*) /api/web/$1 [L]

RewriteCond %{REQUEST_URI} !^/(frontend/web|backend/web|api/web|manager|storage)
RewriteRule (.*) /frontend/web/$1

RewriteCond %{REQUEST_URI} ^/frontend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /frontend/web/index.php [L]


RewriteCond %{REQUEST_URI} ^/backend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward the request to index.php
RewriteRule . /backend/web/index.php [L]


RewriteCond %{REQUEST_URI} ^/api/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward the request to index.php
RewriteRule . /api/web/index.php [L]
конфиг раздела api я не менял, он полностью соответствует конфигу из вашего примера:

Код: Выделить всё

<?php
$params = array_merge(
    require(__DIR__ . '/../../common/config/params.php'),
    require(__DIR__ . '/../../common/config/params-local.php'),
    require(__DIR__ . '/params.php'),
    require(__DIR__ . '/params-local.php')
);

$config =  [
    'id' => 'app-api',
    'basePath' => dirname(__DIR__),
    'controllerNamespace' => 'api\controllers',
    'bootstrap' => ['log'],
    'modules' => [],
    'components' => [
        'request' => [
            'parsers' => [
                'application/json' => 'yii\web\JsonParser',
                'application/xml' => 'yii\web\XmlParser',
            ],
        ],
        'response' => [
            'formatters' => [
                'json' => [
                    'class' => 'yii\web\JsonResponseFormatter',
                    'prettyPrint' => YII_DEBUG,
                    'encodeOptions' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
                ],
            ],
        ],
        'user' => [
            'identityClass' => 'common\models\User',
            'enableAutoLogin' => false,
            'enableSession' => false,
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'urlManager' => [
            //'class'=>'yii\web\UrlManager',
            'enablePrettyUrl' => true,
            'enableStrictParsing' => false,
            'showScriptName' => false,
            'rules' => [
                'api' => 'site/index',
//                '<_c:[\w-]+>' => '<_c>/index',
//                '<_c:[\w-]+>/<id:\d+>' => '<_c>/view',
//                '<_c:[\w-]+>/<id:\d+>/<_a:[\w-]+>' => '<_c>/<_a>',

//                'api/auth' => 'site/login',
                'GET api/profile' => 'api/profile/index',
                'PUT,PATCH api/profile' => 'api/profile/update',

                ['class' => 'yii\rest\UrlRule', 'controller' => 'post'],
            ],
        ],
    ],
    'params' => $params,
];
return $config;
Но при этом у меня все маршруты ведут только на actionIndex!!!
Об этом свидетельствует содержимое xml файла, который отдается браузеру при обращении к разным екшинам:

Код: Выделить всё

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<response>api</response>
Ни какие настройки правил маршрутизации для какого нибудь другого действия кроме index - не срабатывают.

Подскажите пож. в чем может быть проблема?

Заранее спасибо.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение ElisDN »

webgrig писал(а): 2017.12.24, 17:10 Подскажите пож. в чем может быть проблема?
В .htaccess.
webgrig
Сообщения: 163
Зарегистрирован: 2015.10.29, 21:34

Re: Помогите залогиниться через cURL на своем же сайте

Сообщение webgrig »

ElisDN писал(а): 2017.12.24, 23:30 В .htaccess.
А что именно не так в .htaccess?
Ответить