Node.js生成圖形驗證碼--captchapng/ccap/trek-captcha

左岸16發表於2017-11-15

captchapng 是一個使用base64編碼,只能生成數字驗證碼的node模組

使用npm安裝captchapng

npm install --save captchapng

可以通過node.js的http模組搭建伺服器,設定請求的介面地址,然後使用captchapng生成圖形驗證碼返回給客戶端;

var http = require('http');
var captchapng = require('captchapng');

http.createServer(function (request, response) {
    if(request.url === '/captcha') {
        var p = new captchapng(80, 30, parseInt(Math.random() * 9000 + 1000)); // width,height,numeric captcha
        p.color(0, 0, 0, 0);  // First color: background (red, green, blue, alpha)
        p.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha)

        var img = p.getBase64();
        var imgbase64 = new Buffer(img, 'base64');
        response.writeHead(200, {
            'Content-Type': 'image/png'
        });
        response.end(imgbase64);
    } else {
        response.end('');
    }
}).listen(8181);

console.log('Web server started.\n http:\\\\127.0.0.1:8181\\captcha');

使用node執行這個js檔案後,開啟瀏覽器http:\127.0.0.1:8181\captcha,可以看到頁面生成一個圖形驗證碼。

也可以使用Express框架的路由Router,設定後端介面地址,生成圖形驗證碼後返回給客戶端。(可以設定圖形驗證碼的時間戳,為了判斷圖形驗證碼是否過期)

export function loop(num, fn, ruledOut) {
  if (!Type.isNumber(num)) {
      return console.error('[Extend] loop: param 1 is not a number');
  }
  const result = [];
  for (let i = 0; i < num; i++) {
    if (ruledOut) {
      result.push(fn(i));
    } else {
      result[i] = fn(i);
    }
  }

  return result;
}

寫一個controller來設定請求的路徑,在<img>標籤通過src屬性來訪問這個路徑就可以得到圖形驗證碼的圖片來。


import express from 'express';
import Captchapng from 'captchapng';
import { loop } from '../app/lib/utils';

const router = express.Router();

router.get('/captcha', (req, res) => {
  const codeLength = 4;
  const captchaCode = loop(codeLength, () => (
    parseInt((Math.random() * 10000) % 10, 10)
  )).join('');

  const p = new Captchapng(70, 30, captchaCode); // width,height,numeric captcha
  p.color(0, 0, 0, 0);  // First color: background (red, green, blue, alpha)
  p.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha)

  const img = p.getBase64();
  const imgbase64 = new Buffer(img, 'base64');

  if (req.session) {
    req.session.captcha = {
      timestamp: (new Date()).valueOf(),
      code: captchaCode
    };
  }

  res.setHeader('Content-Type', 'image/png');
  res.send(imgbase64);
});

export default router;

在前端頁面中,如何實現點選圖片更換圖形驗證碼呢?

伺服器端編寫好生成驗證碼的方法,由於客戶端瀏覽器會快取URL相同的資源,可以使用隨機數來重新請求:

document.getElementById('captcha').src = '/captcha?' + Math.random();

ccap可以自定義生成的驗證碼型別,預設是字母和數字混合的六位數,驗證碼圖片還帶有干擾線,安全性更高。不過,它好像不支援windows系統,在ios系統上可以使用。同時,它是用C++寫的,在前端專案不用。

import express from 'express';
import Ccap from 'ccap';

const router = express.Router();

const ccap = new Ccap({
  width: 90,
  height: 35,
  offset: 20,
  quality: 300,
  fontsize: 30,
  generate: () => {  // Custom the function to generate captcha text
    const text = loop(4, () => (
      parseInt((Math.random() * 10000) % 10, 10)
    )).join('');
    return text;  // 這裡的變數名只能是text,不能修改!!
  }
});

const ary = ccap.get();  // ary[0] is captcha's text,ary[1] is captcha picture buffer
const graphicCode = ary[0];
const buffer = ary[1];
if (req.session) {
  req.session.captcha = {
    timestamp: (new Date()).valueOf(),
    code: graphicCode
  };
}

if (req.query.base64) {
  res.send('data:image/png;base64,' + buffer.toString('base64'));
} else {
  res.send(buffer);
}

trek-captcha

'use strict'

const fs = require('fs');
const http = require('http');
const captcha = require('trek-captcha');

// async function run() {
//   const { token, buffer } = await captcha();

//   // console.log(token, buffer);

//   fs.createWriteStream('a.gif').on('finish', () => console.log(token)).end(buffer);
// }

// run();

http.createServer(async function(req, res) {
    const { token, buffer } = await captcha();

    console.log(token, buffer);
    res.setHeader('Content-Type', 'image/png');
    res.end(buffer);
}).listen(8123);
console.log('listening at port 8123');

相關文章