<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>webbricks &#187; othAuth</title>
	<atom:link href="http://blog.grzegorzpawlik.com/tag/othauth/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.grzegorzpawlik.com</link>
	<description>Doświadczenie, to coś, co zdobywamy tuż po chwili w której było nam potrzebne ...</description>
	<lastBuildDate>Tue, 07 Feb 2012 10:09:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>CakePHP + nuSOAP serwer + autoryzacja othAuth</title>
		<link>http://blog.grzegorzpawlik.com/2008/02/cakephp-nusoap-serwer-autoryzacja-othauth/</link>
		<comments>http://blog.grzegorzpawlik.com/2008/02/cakephp-nusoap-serwer-autoryzacja-othauth/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 14:23:00 +0000</pubDate>
		<dc:creator>Greg</dc:creator>
				<category><![CDATA[Inne]]></category>
		<category><![CDATA[autoryzacja]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[othAuth]]></category>
		<category><![CDATA[PHP4]]></category>
		<category><![CDATA[PHP5]]></category>
		<category><![CDATA[SOAP]]></category>

		<guid isPermaLink="false">http://meta.vipserv.org/blog.grzegorzpawlik.com/?p=15</guid>
		<description><![CDATA[Autoryzacja serwera soap jest o tyle niewdzięczna, o ile nie została zaimplementowana w samym protokole. Do tego sam cake nie ułatwia nam sprawy. Jednak po wielu dniach zmagań udało mi się nagiąć tą materię i z chęcią się doświadczeniami podzielę &#8230; <a href="http://blog.grzegorzpawlik.com/2008/02/cakephp-nusoap-serwer-autoryzacja-othauth/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Autoryzacja serwera soap jest o tyle niewdzięczna, o ile nie została zaimplementowana w samym protokole. Do tego sam cake nie ułatwia nam sprawy. Jednak po wielu dniach zmagań udało mi się nagiąć tą materię i z chęcią się doświadczeniami podzielę (tak naprawdę po uporaniu się z tym problemem postanowiłem założyć ten blog).<br />
Załóżmy, że serwer, który opisałem w poprzednim poście już stoi. Załóżmy też, że jest zrobione wszystko, co musiało być zrobione, aby autoryzacja othAuth działała w naszej aplikacji (jeśli nie- przed kontynuowaniem zapraszam <a href="http://bakery.cakephp.org/articles/view/othauth-0-5-documentation">tutaj</a> )<br />
Po pierwsze zmieńmy w /app/config/core.php definicję stałej CAKE_SESSION_COOKIE na &#8216;PHPSESSID&#8217; bez tego nie uda nam się &#8220;odzyskać&#8221; sesji znając jej id.<br />
Dalej&#8230; logowanie &#8220;normalnego&#8221; usera wygląda mniej więcej tak:<br />
/app/controllers/user_controller.php<br />
<code lang="php"><br />
function login()<br />
{<br />
if(isset($this->params['data']))<br />
{<br />
$auth_num = $this->othAuth->login($this->params['data']['User']);<br />
return $auth_num;// potrzebne dla soap-owego logowania (1 jeśli udane)<br />
}<br />
}<br />
</code></p>
<p>Wracajmy teraz szybko do naszego oczka w głowie: /app/controllers/soap_controller.php.<br />
W metodzie _defineTypes dodajmy definicję złożonych typów:<br />
<code lang="php"><br />
$this->server->wsdl->addComplexType (<br />
'LoginData',<br />
'complexType',<br />
'struct',<br />
'all',<br />
'',<br />
array(<br />
'Login' => array('name' => 'Login',<br />
'type' => 'xsd:string'), //<br />
'Password' => array('name' => 'Password',<br />
'type' => 'xsd:string'), //<br />
)<br />
);<br />
/**<br />
* odpowiedĹş na logowanie<br />
*/<br />
$this->server->wsdl->addComplexType (<br />
'LoginResponse',<br />
'complexType',<br />
'struct',<br />
'all',<br />
'',<br />
array(<br />
'Result' => array('name' => 'Result',<br />
'type' => 'xsd:int'), //<br />
'SID' => array('name' => 'SID',<br />
'type' => 'xsd:string'), //<br />
)<br />
);<br />
</code></p>
<p>A w metodzie _registerMethods() zarejestrujmy metodę SoapController.login:<br />
<code lang="php"><br />
$this->server->register('SoapController.login',<br />
array('SoapParam' => 'tns:LoginData'),<br />
array('return' => 'tns:LoginResponse') ,<br />
$this->namespace,<br />
$this->namespace . '#login',<br />
'logowanie'<br />
);<br />
</code></p>
<p>Teraz właściwe logowanie:<br />
<code lang="php"><br />
function login($login_data) {<br />
$login_details['User'] = array('username' => $login_data['Login'],<br />
'password' => $login_data['Password'],<br />
'cookie' => "0");<br />
$result = $this->requestAction('users/login', array('data' => $login_details));<br />
return array('Result' => $result, 'SID' => session_id() );<br />
}<br />
</code></p>
<p>Kilka słów wyjaśnienia: w pierwszej linii tworzymy trochę sztucznie tablicę $login_details, która jest taka jaką oczekuje metoda UsersController::login() (zgodnie z zasadą <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> nie będziemy tworzyć osobnej metody dla logowania przez soap). Wywołujemy akcję users/login przekazując do niej spreparowane dane i zwracamy zgodnie z definicją typu LoginResponse- tablicę z danymi.</p>
<p>To była ta łatwiejsza część. Teraz to nad czym spędziłem kilka intensywnych dni- jak odzyskać sesję??<br />
Od razu sprostowanie: wygląda na to, że sesja &#8220;trzyma się&#8221; tak długo, jak długo klient się nie rozłączy (testowałem to za pomocą również nuSOAP + php i w okresie trwania skryptu &#8211; było ok). Jednak ja potrzebowałem możliwości podania przez klienta id sesji, którą otrzymał podczas logowania. Jak to zrobić?<br />
Po kolei:<br />
Dodajmy typ, który będzie służył do przekazania informacji na temat zalogowanego usera:<br />
<code lang="php"><br />
$this->server->wsdl->addComplexType (<br />
'UserDetails',<br />
'complexType',<br />
'struct',<br />
'all',<br />
'',<br />
array(<br />
'Id' => array('name' => 'id',<br />
'type' => 'xsd:int'), //<br />
'Username' => array('name' => 'Username',<br />
'type' => 'xsd:string'), //<br />
'Email' => array('name' => 'Email',<br />
'type' => 'xsd:string'), //<br />
'GroupId' => array('name' => 'GroupId',<br />
'type' => 'xsd:string'), //<br />
'Error' => array('name' => 'Error',<br />
'type' => 'xsd:string')<br />
)<br />
);<br />
</code></p>
<p>Zarejestrujmy metodę SoapController.check():<br />
<code lang="php"><br />
$this->server->register('SoapController.check',<br />
array('data' => 'xsd:string'),<br />
array('return' => 'tns:UserDetails') ,<br />
$this->namespace,<br />
$this->namespace . '#check',<br />
'logowanie'<br />
);<br />
</code></p>
<p>I zdefiniujmy ją:<br />
<code lang="php"><br />
function check($data="") {<br />
$data = $this->requestAction('/users/soapCheck', array('data' => $data, 'SID'=>$data));<br />
$this->log($data, LOG_DEBUG);</p>
<p>if($data){<br />
$return = array ( 'Id' => $data['User']['id'],<br />
'Username' => $data['User']['username'],<br />
'Email' => $data['User']['email'],<br />
'GroupId' => $data['Group']['id'],<br />
'Error' => 'ewrifing ok');<br />
}else{<br />
$return = array ( 'Id' => -1,<br />
'Username' => ''<br />
'Email' => '',<br />
'GroupId' => '',<br />
'Error' => 'not logged in');<br />
}</p>
<p>return $return ;<br />
}<br />
</code></p>
<p>Wyjaśnienia: oprócz danych jak przy logowaniu pojawiło się jeszcze pole w tablicy &#8216;SID&#8217;, to tędy przekażemy informację, że chcemy &#8220;wymusić&#8221; jakieś id sesji.<br />
Teraz metoda UsersController::soapCheck():<br />
<code lang="php"><br />
function soapCheck($data) {<br />
return $this->othAuth->getData();<br />
}<br />
</code></p>
<p>No i na koniec gdzieś musimy wymusić inne id sesji (no bo nie ma przeglądarki, ani kochanych cookies, które zrobią to za nas). W app/app_controller.php:<br />
<code lang="php"><br />
if(isset($this->params['SID'])){<br />
session_id($this->params['SID']);<br />
}<br />
</code></p>
<p>I ok&#8230; jaaasne. Nie działa, prawda? Dlaczego? A to dlatego, że w momencie kiedy klient SOAP łączy się z naszym ukochanym serwerem SOAP wygląda to tak:<br />
<code>request (soap/index) -> app_controller -> soap_contropper -> check -> request (/users/soapCheck) -> app_controller*->users_controller -> soapCheck ...</code></p>
<p>miejsce oznaczone gwiazdką oznacza moment, kiedy app_controller dostaje info o tym, że jest jakieś SID&#8230; tylko że wtedy to już jest za późno (jak to mówią ślązocy: &#8220;po ptokach&#8221; :P) $this-&gt;requestAction to moment, kiedy ciasteczka już nie są wysyłane i szanowna pani Sesja ma już głęboko w &#8230; nosie fakt, że tam jakieś id jest przesyłane.<br />
Nie lękaj się jednak, jest na to rada:<br />
zmień w app_controller poprzednio dodany blok na:<br />
<code lang="php"><br />
if(isset($this->params['url']['SID'])){<br />
session_id($this->params['url']['SID']);<br />
}<br />
</code></p>
<p>I teraz łącząc się z serwerem do linku /twoja_aplikacja/soap/ doklejaj parametr SID=. W takim wypadku już przy pierwszym request-&gt;app_controller id sesji trafia do &#8220;świadomości&#8221; Sesji i zazwyczaj rozpatruje je pozytywnie.</p>
<p>Nie jest to może najbardziej eleganckie rozwiązanie. Jednak najlepsze na jakie teraz mnie stać ;) Jeśli masz coś fajnieszego- pisz w komentarzach, z chęcią się podszkolę :)</p>
<p><span id="formatbar_Buttons" style="display: block;"></span></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.grzegorzpawlik.com/2008/02/cakephp-nusoap-serwer-autoryzacja-othauth/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

