【Axure 教程】驗證碼,除了 12306,我還沒有服過誰(圖形驗證篇)

2 評論 2820 瀏覽 7 收藏 14 分鐘

為了防止暴力注冊或爬蟲爬取等機器請求,需要驗證操作者是人還是機器,便有了驗證碼這個設計。本文作者主要介紹了如何使用 Axure 來設計一個動態的圖形驗證碼,一起來學習一下吧。

在軟件設計中,為了防止暴力注冊或爬蟲爬取等機器請求,需要驗證操作者本尊是人還是機器,因此催生了驗證碼這個設計,目前驗證碼已經衍生出許多的形式,包括圖形驗證、數學運算、點選文字、滑動拼圖等,本文作者主要介紹怎么使用 Axure 來設計一個動態的圖形驗證碼。

一、驗證碼外觀

驗證碼的外觀設計大家可以各自發揮自己的創意,以下是我繪制的,僅供大家參考:

可以給大家提供幾點思路:

  1. 使用識別和閱讀有一定難度的字體,比如帶傾斜、描邊或變形的一些字體
  2. 添加干擾因素,比如線條、背景等
  3. 設置跟背景相近或相似的字體顏色

原則就是能夠盡可能干擾用戶對文字的識別,當然,不能讓用戶完全識別不出來,不然就失去了它存在的意義。

二、驗證碼字庫

常規的圖形驗證碼文字主要由大小寫字母+數字組成,因此我們需要將所有會用到的文字放到字庫中,生成的時候只需要從字庫中挑選即可。為了方便調用,我們使用【全局變量】來存儲字庫,在 Axure 頂部菜單中找到【項目】,點開之后選擇【全局變量】:

接著我們添加一個全局變量【code_library】并輸入默認值,默認值是【0-9,A-Z,a-z】的所有字符:

三、驗證碼位數

一般常見圖形驗證碼都是4位,現在也有一些平臺為了提升難度,會增加到5位或6位,為了能夠靈活控制驗證碼位數,我們也同樣通過變量來控制位數的生成,在【全局變量】中添加【code_bits】,默認值是4:

四、驗證碼存儲

我們生成驗證碼的時候,并不是一下子就從字庫中挑選出指定位數的驗證碼,而是一個一個字符挑選出來,最終組成指定位數的驗證碼,在挑選過程中,需要有一個變量來存儲已經挑選出來的字符,所以,我們還需要一個變量,用來存儲生成的驗證碼,在【全局變量】中添加【code】,無需默認值:

五、驗證碼生成器

上文提到,我們需要按指定位數從字庫中逐一挑選字符來組成驗證碼,也就是說,驗證碼的生成過程是一個循環的過程,因此,我們可以使用一個【動態面板】來作為驗證碼的生成器,當動態面板循環的時候,按照指定的位數從字庫中挑選字符(動態面板如何循環調用可參考我之前發過的文章《【Axure 動態面板】讓你的動畫變成“永動機”》),所以,這里我們先在頁面中拖入一個動態面板,并確保動態面板中至少有2個狀態(狀態中無需放置任何內容,Axure 9.0 建議將動態面板拖動到【負空間】):

至此,我們所有的準備工作就做完了,接下來我們就來實現驗證碼的生成邏輯。

六、驗證碼生成思路

首先,我們先來拆解一下生成的步驟:

總結一下思路:

  1. 當驗證碼載入或被點擊時,驗證碼生成器【動態面板】開始循環;
  2. 生成器循環時,判斷驗證碼【code】的長度是否等于指定的位數【code_bits】,如果是,表示已經從字庫【code_liabrary】中挑選出足夠字符,這時可以停止生成器循環,并把驗證碼顯示出來;
  3. 如果驗證碼的長度【code】不等于指定位數【code_bits】,表示還沒有挑選出足夠的字符,這個時候就從字庫【code_library】隨機挑選一個字符添加到驗證碼【code】中,直到字符數滿足指定的位數,停止生成器循環并將驗證碼顯示出來。

思路基本清晰了,但在動手之前,我們還需要知道這個設計中的一個難點,就是怎么從字庫【code_library】中【隨機】挑選一個字符,這里就會涉及到幾個【函數表達式】:

  1. LVAR.charAt(index):我們可以用這個函數來從字庫【code_library】中取字符,這個函數的作用是從字符串【LVAR】中取出排在【index】位置的字符,這里需要注意,【index】的索引值是從0開始的,也就是說,index = 0 表示取出第一個字符,index = 1 表示取出第二個字符,以此類推,最后一個字符的 index = LVAR.length-1。
  2. Math.random():我們可以用這個函數作為上述函數的索引值【index】,隨機生成取值的索引,這個函數的作用是隨機生成0-1的小數,如果我們要隨機生成0-n的小數,我們只需要將 Math.random() 乘以 n(Math.random() * n) 就行了,這個 n 的取值需要確保在字庫的長度范圍內,超過字庫的長度范圍就會取不到值,所以 n = code_library.length-1 ( index 索引是從0開始,所以要減去1,否則當 n = code_library.length 時會取不到值。
  3. Math.floor(x):Math.random() 生成的是小數,但LVAR.charAt(index) 中的 index 必須是整數,所以我們可以通過這個函數來對Math.random() 生成的小數進行取整,這個函數的作用是返回 x 的下舍整數,簡單說就是將生成的結果,只保留整數,舍去小數部分,例:Math.floor(1.23) = 1。

所以要從字庫中隨機取值,完整的函數表達式就是:code_library.charAt(Math.floor(Math.random()*(code_library.length-1)))。

這下,我們可以開始動手進行配置了。

七、生成驗證碼

首先給驗證碼添加點擊事件,【單擊時】開啟驗證碼生成器(動態面板)循環,循環間隔設為0毫秒即可:

接著,我們給驗證碼生成器添加【狀態改變時】的事件,這里需要區分兩種場景:

場景1:驗證碼位數=指定位數,表示驗證碼生成成功,我們只需要停止生成器循環并把驗證碼顯示出來即可:

場景2:驗證碼位數≠指定位數,表示驗證碼未生成成功,需要從字庫中隨機挑選一個字符添加到驗證碼【code】中:

上圖中后半部分的表達式上文已經解釋過了,這里就不再贅述,關于為什么要在那個表達式前面加上[[code]],這里解釋一下:

假設驗證碼生成器循環4次,每次從字庫中抽出的字符分別是1、2、3、4,如果不加[[code]],則循環4次分別是以下4種結果:

  1. 第一次循環:1
  2. 第二次循環:2
  3. 第三次循環:3
  4. 第四次循環:4

從上面4次循環的結果可以看出,每次生成之后都會給【code】重新賦值,所以【code】永遠都只會有一個數字,就會陷入無限的循環中,而在前面添加[[code]]之后,4次循環的結果是:

  1. 第一次循環:1
  2. 第二次循環:12
  3. 第三次循環:123
  4. 第四次循環:1234

因為每一次循環都會將之前已經生成的【code】拼接到新生成的【code】,再重新賦值給【code】,所以才能形成上述這種追加內容的效果,然后在第四次循環結束之后,驗證碼【code】長度滿足指定長度,退出循環并顯示驗證碼,接下來我們在瀏覽器中看看效果:

效果是對的,但是只有第一次點擊有效,后面怎么點擊都不會變化,哪里出了問題呢?

我們來分析一下,既然第一次點擊能生成說明隨機生成驗證碼的邏輯是沒有問題的,那問題應該是出在判斷驗證碼位數的那個邏輯上,原來,【code】默認是空的,所以第一次點擊的時候能夠正常生成,但是第二次點擊的時候,因為【code】已經有值,所以不會再次生成,所以這里我們在點擊驗證碼時,應該先清空【code】:

這樣就能確保每次點擊驗證碼時【code】都沒有值,才能夠正常生成,再來看看修改后的效果:

現在還有一個問題,就是驗證碼在載入時就會自動生成,但目前還是顯示我們設置的默認文本,這里我們做個簡單的優化,你可以將驗證碼【單擊時】的事件復制粘貼到驗證碼【載入時】的事件中,不過這里有一種更簡單的方式,就是給驗證碼【載入時】添加觸發驗證碼【單擊時】的事件,簡單說就是在驗證碼載入時自動點擊自身并生成:

刷新頁面看看效果:

最后,來驗證一下驗證碼位數控制的功能是否正常,將【code_bits】改為6,再看看效果:

跟預期效果是一樣的,至此,全部教程結束,感謝閱讀。

本文由 @產品錦李 原創發布于人人都是產品經理,未經許可,禁止轉載。

題圖來自Unsplash,基于CC0協議。

該文觀點僅代表作者本人,人人都是產品經理平臺僅提供信息存儲空間服務。

更多精彩內容,請關注人人都是產品經理微信公眾號或下載App
評論
評論請登錄
  1. 好奇,2024年,機器對這種碼已經識別到位,現在還在用這種圖形驗證?

    來自北京 回復
  2. 本文案例原型文件,有需要的讀者歡迎自?。烘溄? https://pan.baidu.com/s/1ULojXFSRY7KBk-dIi0Tw6w?pwd=k6qv 提取碼: k6qv

    來自廣東 回復