實現動態驗證碼的思路

發表於2014-07-03

示例

示例1

背景

驗證碼主要是防止機器暴力破解。之前的驗證碼都是以靜態為主,現在一些產品開始使用動態方式,增加破解的難度。動態方式以 gif 最為簡單可靠。gif 相容性好,尺寸小。這裡分享的就是一種:用 JS 實現 gif 動態驗證碼的思路。感謝關注。

任務分解

  1. 繪製旋轉的文字
  2. 計算每個字元出現位置和角度
  3. 生成 gif 圖片

逐步求精

如何繪製旋轉的文字?

瞭解能用的 API

  • context.rotate(angle) 使當前座標系旋轉 angle,單位弧度
  • context.translate(x, y) 使當前座標系偏移 x, y,單位畫素
  • context.font 設定字型
  • context.strokeText(text, x, y [, maxWidth ]) 給文字描邊
  • context.fillText(text, x, y [, maxWidth ]) 給文字填充

怎麼以文字的中心位置旋轉?

以文字的左下角為圓心旋轉,不符合預期,見下圖效果

示例1

本打算做一下偏移的計算,一想到要計算文字中心位置貌似還挺複雜。 還是看看其他人怎麼做的,通過關鍵詞 canvas rotate text center 找到一點線索。

textAlign 是橫向對齊,再根據標準找到了一個縱向對齊 textBaseline

修改以後,效果符合預期,見下圖:

示例2

按我的習慣就這種 “常用” 功能就封裝成獨立函式,方便以後使用。

如何計算每個字元出現位置和角度?

背景文字左右平移 + 旋轉,生成隨機的字串計算中心座標就好了

前景文字基本相似,只要上下來回移動和稍微搖擺,這裡用的 cos 曲線控制搖擺。

如何生成 gif 圖片

生成 gif 有第三方庫可以使用 gifjs。 這裡要注意的是,gifjs 用到 worker 技術,所以得在 http:// 環境裡除錯,不能用 file:// 環境

注意:由於新增的是同一個 canvas 物件,所以的是使用 copy 模式,將影象資料保留給每一幀。

完整程式碼

後記

功能比較簡單,也寫得比較簡單,僅供參考。如果要應用到實戰,還有很多細節要考慮

  • gif 建立的過程必然得放到後端完成,否則 相容性、效能、安全性 都是問題(這塊和傳統的驗證過程並無區別)。
  • 快取(背景效果可以重複利用一段時間)。
  • 圖片大小需要優化,目前是 200K(通過調整幀率和壓縮比)。
  • 提供方便的呼叫介面(模組化)。

參考資料

相關文章