Добрый день, Когда-то давно писал код для работы с API через SOAP. Код (PHP): $wsdl = 'https://...URL....'; ini_set("soap.wsdl_cache_enabled", "0"); # SOAP object $client = new SoapClient($wsdl, array( 'encoding' => 'UTF-8', ) ); # Login and OAuth token $token = '...........'; # SOAP headers $client->__setSoapHeaders( array( new SoapHeader('API', 'token', $token, false) ) ); $result = $client->....... Авторизация по Токену работала передаваясь в заголовке SOAP запроса. Всё было ок. Тех.поддержка API , поменяла принцип авторизации, и теперь просит указывать токен в HTTP-заголовке, а не в SOAP запросе. То есть, требуется послать нечто: POST /....URL.../ HTTP/1.1 Authorization: Bearer token Accept-Language: ru Content-Type: charset=utf-8 т.е. теперь нужно как-то обернуть SOAP чтобы перед этим он посылал необходимый токен в HTTP запросе типа Authorization: Bearer token? может кто подсказать код? не пойму как это сделать Подсказка от модератора: Любой код или текст конфигурации пишите между тегом [code=php] и [/code]. Используйте отступы в коде для форматирования текста. Это помогает быстрее понять вас, увеличивает шанс на получение ответа. Что выделять? Например: PHP, HTML, CSS, JavaScript, SQL, XML, .htaccess, ini, регулярные выражения, код шаблонизаторов, любая другая разметка, результаты array/object dump и т. д.
Поиск по ключевым словам: "php SoapClient add http headers" Этот вариант пробовал? http://stackoverflow.com/questions/6179138/soapclient-set-c ... ttp-header
denis01, да, уже несколько дней гуглю, что-то не получается вариант этот тоже пробовал. делаю так: Код (PHP): $wsdl = 'https://domen.com/service?wsdl/'; $token = '.....................'; ini_set("soap.wsdl_cache_enabled", "0"); $client = new SoapClient($wsdl, array( "exceptions" => 0, "trace" => 1, "encoding" => 'UTF-8', 'stream_context' => stream_context_create( array('http' => array('header' => 'Authorization: Bearer $token'))))); $result = $client->check(); print_r($client); Может неправильный синтаксис выше, насчёт Bearer: array('header' => 'Authorization: Bearer $token'))))); получаю ответ что авторизация не прошла, т.к. Токен не введён: print_r($client); выдаёт: Код (Text): SoapClient Object ( [trace] => 1 [_exceptions] => [_encoding] => UTF-8 [_stream_context] => Resource id #2 [_soap_version] => 1 [sdl] => Resource id #5 [__last_request] => <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://domen.com/service"><SOAP-ENV:Body><ns1:CheckRequest/></SOAP-ENV:Body></SOAP-ENV:Envelope> [httpurl] => Resource id #7 [__last_request_headers] => POST /service HTTP/1.1 Host: soap.domen.com Connection: Keep-Alive User-Agent: PHP-SOAP/5.2.13 Content-Type: text/xml; charset=utf-8 SOAPAction: "https://domen.com/service/check" Content-Length: 240 [__last_response_headers] => HTTP/1.1 200 OK Server: nginx Date: Sun, 28 Feb 2016 12:00:54 GMT Content-Type: text/xml Transfer-Encoding: chunked Connection: close X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff [__last_response] => <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>Authorization error</faultstring><detail><ns3:FaultResponse xmlns:ns3="http://domen.com/general"><requestId>12345</requestId><errorCode>12345</errorCode><errorDetail>Token not entered</errorDetail></ns3:FaultResponse></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope> [__soap_fault] => SoapFault Object ( [message:protected] => Authorization error [string:private] => [code:protected] => 0 [file:protected] => api.php [line:protected] => 53 [trace:private] => Array ( [0] => Array ( [function] => __call [class] => SoapClient [type] => -> [args] => Array ( [0] => check [1] => Array ( ) ) ) [1] => Array ( [file] => api.php [line] => 53 [function] => check [class] => SoapClient [type] => -> [args] => Array ( ) ) ) [faultstring] => Authorization error [faultcode] => SOAP-ENV:Client [detail] => stdClass Object ( [FaultResponse] => stdClass Object ( [requestId] => 12345 [errorCode] => 12345 [errorDetail] => Token not entered ) ) ) ) Добавлено спустя 13 минут 16 секунд: + есть: Адрес WSDL-описания https://domen.com/service?wsdl Адрес для SOAP-запросов https://domen.com/service Может надо стрим_контекст с Авторизацией посылать на УРЛ Адрес для SOAP-запросов? А не на wsdl? В моём коде речь ведь только про wsdl: $wsdl = 'https://domen.com/service?wsdl/'; или это не важно? Хотя вроде пишут что если SOAP поддерживает WSDL то не важно, там само опредлеяется.
Алексей, сам же ссылаешься на топик: http://php.ru/forum/viewtopic.php?t=50318, а ведь именно там и есть ответ на вопрос, заголовки отдавай.
Ke1eth делаю: Код (PHP): <span class="syntaxdefault"><br />var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"REQUEST"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> $client</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">__getLastRequest</span><span class="syntaxkeyword">());<br /></span><span class="syntaxdefault">var_dump</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"RESPONSE"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> $client</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">__getLastResponse</span><span class="syntaxkeyword">());<br /></span><span class="syntaxdefault"></span> получаю: Код (Text): string(7) "REQUEST" string(240) "<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://domen.com/service"><SOAP-ENV:Body><ns1:CheckRequest/></SOAP-ENV:Body></SOAP-ENV:Envelope> " string(8) "RESPONSE" string(505) "<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>Authorization error</faultstring><detail><ns3:FaultResponse xmlns:ns3="http://domen.com/general"><requestId>12345</requestId><errorCode>53</errorCode><errorDetail>Token not entered</errorDetail></ns3:FaultResponse></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope> " Добавлено спустя 37 минут 1 секунду: а почему: Код (PHP): var_dump("REQUEST", $client->__getLastRequest()); и то что он отдал выше: string(240) и т.д., не показывает что мы делали заголовок стрим_контекстом stream_context: Код (PHP): array('header' => 'Authorization: Bearer $token'))))); Добавлено спустя 32 минуты 24 секунды:нашёл что в php 5.2. но в каких точно версиях не ясно, есть баг со stream_context: https://bugs.php.net/bug.php?id=41051 но делая замену Код (PHP): array('http' => array('header' => 'Authorization: Bearer $token'))))); на Код (PHP): array('http' => array('header' => array('Authorization' => 'Bearer $token')))))); ответ тот же самый как и выше - нет токена. Добавлено спустя 4 минуты 54 секунды: посмотрел по print_r($client) который приводил выше тут viewtopic.php?f=13&t=56916&p=458453#p458431: Код (Text): [httpurl] => Resource id #7 [__last_request_headers] => POST /service HTTP/1.1 Host: soap.domen.com Connection: Keep-Alive User-Agent: PHP-SOAP/5.2.13 Content-Type: text/xml; charset=utf-8 SOAPAction: "https://domen.com/service/check" Content-Length: 240 так у нас же никакой Authorization Bearer токен не передаётся?! Получается stream_context не работает? Добавлено спустя 9 минут 32 секунды: или он там и не должен быть? потому что это SoapClient Object, а токен надо передать ВНЕ SoapClient Object, а не внутри как это обычно деают по new SoapHeader. Добавлено спустя 6 минут 39 секунд: нет токен там быть должен, т.к. если мы делаем заголовок для СОАП-запроса, то он будет как: Код (Text): SoapClient Object ( [trace] => 1 [_exceptions] => [_encoding] => UTF-8 [_soap_version] => 1 [sdl] => Resource id #3 [__default_headers] => Array ( [0] => SoapHeader Object ( [namespace] => API [name] => token [data] => [mustUnderstand] => ) ) а нам нужно отддать токен именно в заголовке HTTP last_request_headers Код (Text): [__last_request_headers] => POST /service HTTP/1.1 Host: soap.domen.com Connection: Keep-Alive User-Agent: PHP-SOAP/5.2.13 Content-Type: text/xml; charset=utf-8 SOAPAction: "https://domen.com/service/check" Content-Length: 240
верный точно, на принимающем сервере 2 версии API. старая работает по токену который передаётся ВНУТРИ соап-объекта, через: Код (PHP): new SoapHeader('API', 'token', $token, false) так всё ок. а новая версия "смотрит" заголовки не СОАП объека, а именно HTTP-заголовки. т.е. она ждёт: Код (Text): POST url HTTP/1.1 Host: domen.com Authorization: Bearer Accept-Language: ru Content-Type: application/json; charset=utf-8 а делая print_r($client) вижу что мы отдаём: Код (Text): [__last_request_headers] => POST /service HTTP/1.1 Host: soap.domen.com Connection: Keep-Alive User-Agent: PHP-SOAP/5.2.13 Content-Type: text/xml; charset=utf-8 SOAPAction: "https://domen.com/service/check" Content-Length: 240 без всяких Authorization: Bearer но Authorization: Bearer -то мы прописывает же в stream_context. Почему его тогда нет в [__last_request_headers]. об этом кстати в БАГе и сказано: https://bugs.php.net/bug.php?id=41051
вроде бы нашёл баг какой-то там косяк в SOAP со stream_context только какой не особо пока понял, но решения указать 'protocol_version' => 1.1 и закрыть соединение "Connection: close" ни к чему не приводит всё равно. https://bugs.php.net/bug.php?edit=1&id=49853 может кто объяснить в чём там суть? Добавлено спустя 27 минут 37 секунд: на php 5.4.41 stream_context вместе c SOAP работает! и в [__last_request_headers] есть токен по print_r($client); на 5.2.13-17 - не работает stream_context с SOAP. Но на многих серверах он стоит, как можно пофиксить?
Сейчас PHP 7 актуальная (ещё поддерживают 5.6 и 5.5), зачем писать под неподдержимую 5.2 и т. д. На хостингах есть обычно возможность переключения версий PHP.