2011年3月17日 星期四

cURL 模組

較傳統的網站間驗證帳號方式,是利用表單將帳號密碼傳到對方的網站,當驗證成功則回到原來網站。如果失敗,則停在對方的網頁,或是導向錯誤訊息頁面。利用瀏覽器轉向(redirect)的方式,甚至可以讓使用者沒有發覺自己曾經連到其它網站。

最近製作的專案,就是為了串接這種模式的帳號驗證,不過這次使用的平台是 AIR 應用程式,無法使用瀏覽器的轉向功能。所以只用其它方式,在 server 端把原來表單資料傳遞的行為重現出來。

和同事討論過可能的作法,他建議使用 PHP 的 cURL 模組。它是用來可以作為要發出 HTTP 要求的工具,和其它人可能會想到的 fopen 方法不同之處,它可以帶著 POST 以及 COOKIE 設定資料,這是 fopen 所作不到的(它頂多只能傳遞 GET 數值)。另外,它也能接收由對方傳回來的 http header,也就是可以收到對方傳來的 COOKIE 設定。

講了那麼多 COOKIE ,是因為我這次需要模擬的,就是利用在瀏覽器中記錄 COOKIE 的方式達到驗證的行為,有 COOKIE 資料,才能合法的取得使用者相關資料。

在介紹程式碼之前,要先說明的是 cURL 並不是大部分 PHP 預設啟用的模組,所以使用前要先檢查已經安裝及啟用。可以由 phpinfo() 輸出的結果得知。

網路上有不少資料可以參考,這裡只拿我所使用的程式片斷為例子說明︰
// 和 fopen 類似,首先要先建立連線,以傳回來的資料作為後續操作之用
$ch = curl_init();

// 使用 curl_setopt 來設定連線參數
curl_setopt($ch, CURLOPT_URL, '連線目標網址');  // 設定連線目標
curl_setopt($ch, CURLOPT_POST, TRUE);              // 使用 POST 傳遞資料
curl_setopt($ch, CURLOPT_POSTFIELDS, 'username=name&passwd=pass'); // POST 資料
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // 當設定為 true 表示要接到網頁內容
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie 存放檔案位置'); // 設定儲存 cookie 資訊

// 發出要求
$result = curl_exec($ch);
// 由於在 CURLOPT_RETURNTRANSFER 設定為 TRUE ,所以我會收到網頁內容,否則只會依要求成功與否傳回  TRUE/FALSE 資料

// 用完的東西關閉是好習慣 ^ ^
curl_close($ch);

關於 cookie 的部分,花了滿多時間在找資料,沒有看到任何不經過檔案直接取得變數的管道,所以最後還是只能乖乖的把檔案打開,裡面的格式是用 Netscape 格式來儲存,前面幾行註解,在一個空行之後,以 "\t" 的方式,一個變數一行來宣告。相信對字串處理熟悉的人,把 cookie 值抓出來不是困難的事。

至於怎麼送出  cookie 資料呢?可以在設定參數的時候加上︰
curl_setopt($ch, CURLOPT_COOKIE, 'key=value');
來作設定,不過我還不了解的是,這樣要怎麼設定 cookie 所屬的網域(domain)勒?
不過實際測試,收到要求的網站好像依然讀得到,很順利的讀出來。

另外一種方式,則是可以用之前提到的 cookie 檔案來傳,只要使用︰
curl_setopt($ch, CURLOPT_COOKIEFILE, '檔案路徑');
感覺起來,這算是比較保險的作法。

至於 curl 裡面還有另個 multi 系列的函數,似乎是一次可以對不同對象網址發出要求,不過因為已經超過我這個專案的需求了,時間因素就沒有再研究下去了。

1 則留言:

  1. 今天又再一次使用這個功能,查了文件,發現
    curl_setopt($ch, CURLOPT_POSTFIELDS, [參數])
    可以接受值名對的陣列,真是一個不錯的發現,
    這樣就不需要靠自己去作 urlencode ,程式也比較清楚易讀。

    回覆刪除