码迷,mamicode.com
首页 > 其他好文 > 详细

cowboy添加验证码

时间:2015-04-14 12:47:24      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

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

注意,需要cowboy版本1.0.1

 

创建工程

rebar-creator create-app testCowboy

 

testCowboy_app.erl

技术分享
-module(testCowboy_app).

-behaviour(application).

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

-define(C_ACCEPTORS,  100).

start(_StartType, _StartArgs) ->
    application:start(crypto),
    application:start(cowlib),
    application:start(ranch),
    application:start(cowboy),

    Routes    = route_helper:get_routes(),
    Dispatch  = cowboy_router:compile(Routes),
    Port      = 8080,
    TransOpts = [{port, Port}],
    ProtoOpts = [{env, [{dispatch, Dispatch}]}],
    cowboy:start_http(http, ?C_ACCEPTORS, TransOpts, ProtoOpts).

stop(_State) ->
    ok.

技术分享

 

route_helper.erl

-module(route_helper).

-export([get_routes/0]).

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

captcha_handler.erl
-module(captcha_handler).

-export([init/3]).
-export([handle/2]).
-export([terminate/3]).

init(_Transport, Req, []) ->
  {ok, Req, undefined}.

handle(Req, State) ->
  %codeHex用于验证的时候用,需本地保存,CapCode为用户提交的数据
  %mycaptcha:check(CodeHex, CapCode)
  {CodeHex, BinPng} =  mycaptcha:new(),
  Req2 = cowboy_req:set_resp_cookie(<<"cap">>, CodeHex, [{path, <<"/">>}], Req),
  {ok, Req3} = cowboy_req:reply(200, [{<<"content-type">>, <<"image/png">>}],BinPng, Req2),
  {ok, Req3, State}.

terminate(_Reason, _Req, _State) ->
  ok.

 

mycaptcha.erl
-module(mycaptcha).
-compile(export_all).

new() ->
    CryptKey = case ets:info(captcha) of
        undefined ->
            captcha = ets:new(captcha, [set, public, named_table]),
            CK = crypto:rand_bytes(16),
            true = ets:insert(captcha, {CK}),
            CK;

        _Info ->
            ets:first(captcha)
    end,

    FileName = lists:flatmap(fun(Item) -> integer_to_list(Item) end, tuple_to_list(now())),

    Code = generate_rand(5),

    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),

    Sha = crypto:sha_mac(CryptKey, integer_to_list(lists:sum(Code)) ++ Code),
    CodeHex = mochihex:to_hex(Sha),
 
    {CodeHex, BinPng}.

check(CodeHex, Code) ->
    Sha = mochihex:to_bin(CodeHex),
    CryptKey = ets:first(captcha),

    case crypto:sha_mac(CryptKey, integer_to_list(lists:sum(Code)) ++ Code) of
        Sha ->
            true;

        _ ->
            false
    end.

generate_rand(Length) ->
    Now = now(),
    random:seed(element(1, Now), element(2, Now), element(3, Now)),
    lists:foldl(fun(_I, Acc) -> [do_rand(0) | Acc] end, [], lists:seq(1, Length)).

do_rand(R) when R > 46, R < 58; R > 64, R < 91; R > 96 ->  
    R;

do_rand(_R) ->
    %do_rand(48 + random:uniform(74)). %% exluding zero
    do_rand(47 + random:uniform(75)).

 

moche_hex.erl

自己下载

 

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/testCowboy", "rel"]}.

 

测试html

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

 

  

cowboy添加验证码

标签:

原文地址:http://www.cnblogs.com/ziyouchutuwenwu/p/4424499.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!