2012年6月28日 星期四

php & curl & session

最近在試著利用curl去取得某api回傳的結果,
過程是這樣的:
A網頁呼叫B網頁做登入,完成之後,
A網頁呼叫C網頁取得需要的資料,

但是取得C網頁資料的時候必須使用到B網頁登入後產生的SESSION的資料:

//中斷A網頁session寫入的動作
session_write_close();

//B與C網頁的url
$b_url = 'http://api.example.com/login';
$c_url = 'http://api.example.com/get_data';

//先登入B網頁
$b_ch = curl_init($b_url);
curl_setopt($b_ch, CURLOPT_POST, 1);
curl_setopt($b_ch, CURLOPT_RETURNTRASFER, 1);
curl_setopt($b_ch, CURLOPT_POSTFIELD, 'username=test&password=love5566');
curl_setopt($b_ch, CURLOPT_COOKIE, session_name().'='.session_id());
curl_setopt($b_ch, CURLOPT_TIMEOUT, 10);
curl_exec($b_ch);
curl_close();

//再去C網頁取得資料
$c_ch = curl_init($c_url);
curl_setopt($c_ch, CURLOPT_POST, 1);
curl_setopt($c_ch, CURLOPT_RETURNTRASFER, 1);
curl_setopt($c_ch, CURLOPT_COOKIE, session_name().'='.session_id());
curl_setopt($c_ch, CURLOPT_TIMEOUT, 10);
$result = curl_exec($c_ch);
curl_close();

$result便是C網頁回傳的網頁內容了,
關鍵在curl_setopt($c_ch, CURLOPT_COOKIE, session_name().'='.session_id()),
讓兩個curl在執行時用的都是同一個session_id的session,


中間這樣嘗試的時候發覺會一直卡住,查了之後才發現是被鎖住了,

參考網頁:http://www.smooka.com/blog/2009/07/24/maintaining-php-session-when-using-curl/

裡面說到:
What does session_write_close() do? It, ends the current session and store session data. Apparently, PHP does not like when multiple scripts play around with the session, so, it locks it. Putting session_write_close makes sure that your current session is stored so you can retrieve it and use it.


所以在前面加上了session_write_close()之後,問題就解決了,
不過對於一個API來說,在取得資料還必須丟session_id給他似乎哪裡怪怪的,
也許有安全上的疑慮?
我想應該弄個類似open id這種使用access token的驗證機制應該會像樣一點。



沒有留言:

張貼留言