cowboy添加验证码
参考的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>
收工
cowboy添加验证码的更多相关文章
- asp.net添加验证码
1.新建一个aspx页面生成验证码图像 using System; using System.Data; using System.Configuration; using System.Collec ...
- PHPCMS v9 自定义表单添加验证码验证
1. 在 \phpcms\templates\default\formguide\show.html 中添加验证码显示 <input type="text" id=" ...
- Angular企业级开发(9)-前后端分离之后添加验证码
1.背景介绍 团队开发的项目,前端基于Bootstrap+AngularJS,后端Spring MVC以RESTful接口给前端调用.开发和部署都是前后端分离.项目简单部署图如下,因为后台同时采用微服 ...
- PHPCMS v9 自定义表单添加验证码
1. 在 \phpcms\templates\default\formguide\show.html 中添加验证码显示 <input type="text" id=&quo ...
- cas4.2.4 登添加验证码
看了很多添加验证码的博文,唯独没有4.24的 重点看第3条,其余的和别人博文大致相同 1.首先在cas工程的web.xml增加验证码功能的支持 <!-- 验证码功能 --> &l ...
- [phpcms v9]自定义表单添加验证码验证功能
修改 \phpcms\templates\default\formguide\show.html 中添加验证码显示 <input type="text" id=" ...
- 【转】PHPCMS v9 自定义表单添加验证码验证
1. 在 \phpcms\templates\default\formguide\show.html 中添加验证码显示 <input type="text" id=&quo ...
- C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库
C# DateTime的11种构造函数 别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...
- cas添加验证码
cas添加验证码,折腾了好久,终于整理好了,很大部分都是借鉴http://binghejinjun.iteye.com/blog/1255293这个的.但是他的有一个很不好的地方就是不能提升验证码错误 ...
随机推荐
- 20155201 实验二《Java面向对象程序设计》实验报告
20155201 实验二<Java面向对象程序设计>实验报告 一.实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. ...
- 浅谈HashMap 的底层原理
本文整理自漫画:什么是HashMap? -小灰的文章 .已获得作者授权. HashMap 是一个用于存储Key-Value 键值对的集合,每一个键值对也叫做Entry.这些个Entry 分散存储在一个 ...
- 全局变量的使用【C++/Qt】
转:https://blog.csdn.net/caoshangpa/article/details/51104022 一.使用extern关键字 cglobal.h #ifndef CGLOBAL_ ...
- 导入tensorflow:ImportError: libcublas.so.9.0: cannot open shared object file: No such file or director【转】
本文转载自:https://blog.csdn.net/ksws0292756/article/details/80034086 版权声明:本文为博主原创文章,转载请一定附上博主原文链接,并署名转自Z ...
- dynamic load javascript file.
$.ajax({ url : ("js/public/" + window.localStorage.getItem("lang") + ".js&q ...
- 读写 Excel 工作表
导入诸如 CSV 之类文本格式的数据的优点是不需要依靠某些特定软件来读取数据,并且文件具有可读性,即软件中性.然而,它的缺点也很明显——我们不能直接对文本编辑器中的数据执行计算操作,因为这些内容是纯文 ...
- Qt5_TCP_Client01
ZC: 代码来自<<Qt及Qt Quick开发实战精解>>“代码\src\5\5-3”(“代码\src\5\5-4”里面的代码差不多,不知有何差别...貌似应该是更为完善) Z ...
- 语义化标签和media媒体查询可以放心使用
现在的高级浏览器都支持html5,只有IE6-IE8不支持.(下面说的IE均值IE6-IE8) 有两个特性在IE是可以使用的: 1.语义化标签: header(头部) section(区块) foot ...
- 一次由webview报错引起的追根溯源
最近客户端那边需要搞了个h5嵌入app,想想是移动端的webview,前端这边也比较忙.就没想太多,直接用了async/await处理api数据,于是就不怪测试就来搞事情了... 一.error: 1 ...
- JSP 指令
JSP 指令 JSP指令用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言. 语法格式如下: <%@ directive attribute="value" %&g ...