参考的http://beebole.com/blog/erlang/how-to-implement-captcha-in-erlang-web-application/,移到cowboy,修改了下;废话不多说,直接贴代码

注意,需要cowboy版本1.0.1

需要imagemagick

sudo apt-get install imagemagick

mac

brew install imagemagick

mac下如果使用convert命令找不到字体,则需要安装下这个

brew install ghostscript

创建工程

rebar-creator create-app testCaptcha

testCaptcha_app

-module(testCaptcha_app).

-behaviour(application).

-export([start/, stop/]).

-define(C_ACCEPTORS,  ).

start(_StartType, _StartArgs) ->

    simple_captcha_ets:init(),

    application:start(crypto),
application:start(cowlib),
application:start(ranch),
application:start(cowboy), Routes = route_helper:get_routes(),
Dispatch = cowboy_router:compile(Routes),
Port = ,
TransOpts = [{port, Port}],
ProtoOpts = [{env, [{dispatch, Dispatch}]}],
cowboy:start_http(http, ?C_ACCEPTORS, TransOpts, ProtoOpts). stop(_State) ->
simple_captcha_ets:destroy(),
ok.

route_helper
-module(route_helper).

-export([get_routes/]).

get_routes() ->
[
{'_', [
{"/captcha", captcha_handler, []},
{"/captcha_check", captcha_check_handler, []}
]}
].

simple_captcha
-module(simple_captcha).

-export([create/,check/]).

create() ->
CryptKey = mochihex:to_hex(crypto:rand_bytes()),
Code = generate_rand(), FileName = lists:flatmap(fun(Item) -> integer_to_list(Item) end, tuple_to_list(now())),
File = io_lib:format("/tmp/~s.png",[FileName]), Cmd = io_lib:format("convert -background 'none' -fill '#222222' -size 175 -gravity Center -wave 5x100 -swirl 50 -font DejaVu-Serif-Book -pointsize 28 label:~s -draw 'Bezier 10,40 50,35 100,35 150,35 200,50 250,35 300,35' ~s", [Code, File]),
os:cmd(Cmd), {ok, BinPng} = file:read_file(File),
file:delete(File), simple_captcha_ets:insert(Code,CryptKey), {erlang:list_to_bitstring(CryptKey),BinPng}. check(CryptKeyBitString,CodeBitString) ->
CryptKey = erlang:bitstring_to_list(CryptKeyBitString),
Code = erlang:bitstring_to_list(CodeBitString),
CryptKeyFromEts = simple_captcha_ets:find(Code), case string:equal(CryptKeyFromEts,CryptKey) of
true ->
simple_captcha_ets:remove(code),
true;
_ ->
false
end. %private
generate_rand(Length) ->
Now = now(),
random:seed(element(, Now), element(, Now), element(, Now)),
lists:foldl(fun(_I, Acc) -> [do_rand() | Acc] end, [], lists:seq(, Length)). do_rand(R) when R > , R < ; R > , R < ; R > ->
R; do_rand(_R) ->
do_rand( + random:uniform()).
simple_captcha_ets
-module(simple_captcha_ets).

-export([init/,insert/,find/,remove/,destroy/]).

init()->
TableName = ets:new(simple_captcha, [public,named_table]),
{ok, TableName}. insert(Key,Value) ->
ets:insert(simple_captcha, {Key, Value}),
ok. find(Key) ->
Result = (
try ets:lookup_element(simple_captcha, Key, ) of
Value ->
Value
catch
_:_ ->
""
end
),
Result. remove(Key) ->
try ets:delete(simple_captcha, Key)
catch
_:_ ->
ok
end. destroy()->
try ets:delete(simple_captcha)
catch
_:_ ->
ok
end.
mochihex
自己下载
captcha_handler
-module(captcha_handler).

-export([init/]).
-export([handle/]).
-export([terminate/]). init(_Transport, Req, []) ->
{ok, Req, undefined}. handle(Req, State) ->
%CryptKey用于验证的时候用,需本地保存,CapCode为用户提交的数据
%simple_captcha:check(CryptKey, CapCode)
{CryptKey,BinPng} = simple_captcha:create(), Req2 = cowboy_req:set_resp_cookie(<<"cap">>, CryptKey, [{path, <<"/">>}], Req),
{ok, Req3} = cowboy_req:reply(, [{<<"content-type">>, <<"image/png">>}],BinPng, Req2),
{ok, Req3, State}. terminate(_Reason, _Req, _State) ->
ok.
captcha_check_handler
-module(captcha_check_handler).

-export([init/]).
-export([handle/]).
-export([terminate/]). init(_Transport, Req, []) ->
{ok, Req, undefined}. handle(Req, State) ->
{CryptKey,_} = cowboy_req:cookie(<<"cap">>, Req,<<"">>),
{ok, PostVals, Req2} = cowboy_req:body_qs(Req),
CaptchaCode = proplists:get_value(<<"captchaCode">>, PostVals), case simple_captcha:check(CryptKey, CaptchaCode) of
true ->
{ok, Req3} = cowboy_req:reply(, [{<<"content-type">>, <<"text/html">>}],<<"ok">>, Req2),
{ok, Req3, State};
_ ->
{ok, Req3} = cowboy_req:reply(, [{<<"content-type">>, <<"text/html">>}],<<"error">>, Req2),
{ok, Req3, State}
end. terminate(_Reason, _Req, _State) ->
ok.

rebar.config

% -*- erlang -*-
{erl_opts, [debug_info]}.
{deps, [
{cowboy,".*", {git, "https://github.com/ninenines/cowboy", {tag,"1.0.1"}}}
]}.
{cover_enabled, true}. {eunit_opts, [verbose, {report,{eunit_surefire,[{dir,"."}]}}]}.
{sub_dirs, ["apps/testCaptcha", "rel"]}.

run.sh

#!/bin/sh
rebar clean;
rebar compile;
erl -pa apps/*/ebin deps/*/ebin -eval "application:start(testCaptcha)."

captcha_test.html

<img src="http://127.0.0.1:8080/captcha" width="" height="">

<form action="http://127.0.0.1:8080/captcha_check" method="post">
<p>captcha<input type="text" name="captchaCode" /></p>
<input type="submit" value="Submit" />
</form>

收工

最新文章

  1. Hyper-V 与Broadcom网卡兼容问题
  2. Java c3p0连接池
  3. illustrator将图片转换成ai路径
  4. jeecg扩展封装tag的那些事
  5. C++的Trigraph
  6. 一些有用的UtilityExtend小方法
  7. Android Studio项目引入外部库注意事项(PullToRefresh)
  8. 黄聪:MySql Host is blocked because of many connection errors; unblock with &#39;mysqladmin flush-hosts&#39; 解决方法(转)
  9. 层叠样式优先级CSS
  10. DAL – RDBMS 的分区
  11. tree btn
  12. JSP-页面跳转大全
  13. iOS-改变UITextField的Placeholder颜色的三种方式
  14. PS 图像特效算法— —渐变
  15. 小项目一---Python日志分析
  16. springmvc java配置
  17. 新建oracle数据库表空间及删除表空间和用户
  18. python selenium right click on an href and choose Save link as... on Chrome.
  19. C#使用双缓存减少界面闪烁
  20. selenium模拟鼠标操作

热门文章

  1. linux读书笔记第三章
  2. 20155201 实验五《Java面向对象程序设计》实验报告
  3. [转][修]sprintf()函数:将格式化的数据写入字符串
  4. 子网掩码与ip有实际关系吗?
  5. ongene database
  6. BZOJ3239 Discrete Logging
  7. IIS上部署DotNet Core程序
  8. cvs的规范以及介绍(转)
  9. -webkit新属性 image-set和srcset
  10. 穷举算法和递推算法(Java)