Wabow Information Inc. Blog
分類: 技術分享 作者: daniel
27 八月 2009感謝上一篇文章中前輩們的熱心回覆;垃圾留言果然是大家心中的痛啊(噗)~雖然 CAPTCHA 可以透過各式各樣的 OCR 破解(最新版的 JDownloader 也已經能忽略大部分免費空間所用的圖像辨識...扯遠了),不過它仍是目前阻擋機器人最直接也最簡單的解決方案;當然更複雜的 CAPTCHA 還是能夠達到阻擋的目的,但是使用 CAPTCHA 的方式對使用者來說就已經是不友善了。
後來在討論中 Jace 提到,其實 SESSION 是有可能被機器人知道的;所以我後來綜合了 fillano 提供的演算法概念,稍微改良了一下之前的 NoSpamNX class。利用隨機產生的隱藏欄位順序,用不同的演算法再對隱藏欄位的數值作編碼;讓 SESSION 內存的未編碼的值,與 POST 過來的已編碼的值不一樣。最後再將 SESSION 內存的值編碼,與 POST 的已編碼的值作比較,判斷留言的使用者是不是機器人。
SESSION 紀錄的值是未編碼的值,但在產生隱藏欄位時,input 的值是已經編碼過後的值
/** * 建立隱藏欄位 HTML;利用隱藏欄位先後順序不同,使用 md5 or sha1 編碼 * */ public function addHiddenFields() { $nospamnx = $_SESSION[$this->_sessionName]; if (1 === rand(1,2)) { return '<input type="text" name="nospamnx['.$nospamnx['nospamnx-1'].']" value="" class="locktross" /><input type="text" name="nospamnx['.$nospamnx['nospamnx-2'].']" value="'.md5($nospamnx['nospamnx-2-value']).'" class="locktross" />'; } else { return '<input type="text" name="nospamnx['.$nospamnx['nospamnx-2'].']" value="'.sha1($nospamnx['nospamnx-2-value']).'" class="locktross" /><input type="text" name="nospamnx['.$nospamnx['nospamnx-1'].']" value="" class="locktross" />'; } }
驗證時根據 POST 過來的 nospamnx 順序不同,以不同的演算法編碼後再做比較
// 根據 POST 過來的值順序不同,以 md5 or sha1 判斷 if ($nospamnx['nospamnx-1'] == current(array_keys($postData))) { $encode_value = md5($nospamnx['nospamnx-2-value']); } else { $encode_value = sha1($nospamnx['nospamnx-2-value']); } if ($postData[$nospamnx['nospamnx-2']] != $encode_value) { return false; }
最後提供範例程式下載,分為一般 POST 與 AJAX 二種方式。