NutzBook - 登陆验证码

NutzBook - 登陆验证码

Tags: Nutz

摘要

NutzBook - 登陆验证码

新增jar

simplecaptcha-1.2.2.jar

<!-- http://mvnrepository.com/artifact/cn.apiclub.tool/simplecaptcha -->
<dependency>
    <groupId>cn.apiclub.tool</groupId>
    <artifactId>simplecaptcha</artifactId>
    <version>1.2.2</version>
</dependency>

新增CaptchaModule模块类

package net.javablog.module;

import cn.apiclub.captcha.Captcha;
import cn.apiclub.captcha.backgrounds.GradiatedBackgroundProducer;
import cn.apiclub.captcha.gimpy.FishEyeGimpyRenderer;
import net.javablog.util.Toolkit;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;

import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;

@IocBean
@At("/captcha")
public class CaptchaModule {

    @At
    @Ok("raw:png")
    public BufferedImage next(HttpSession session, @Param("w") int w, @Param("h") int h) {
        if (w * h < 1) { //长或宽为0?重置为默认长宽.
            w = 200;
            h = 60;
        }
        Captcha captcha = new Captcha.Builder(w, h)
                .addText().addBackground(new GradiatedBackgroundProducer())
//                                .addNoise(new StraightLineNoiseProducer()).addBorder()
                .gimp(new FishEyeGimpyRenderer())
                .build();
        String text = captcha.getAnswer();
        session.setAttribute(Toolkit.captcha_attr, text);
        return captcha.getImage();
    }

}

关键点

  • raw代表RawView
  • png是RawView中对image/png的缩写,是数据mime的描述
  • 返回值是BufferedImage,且这是image/png, 所以会转为图片显示. 还支持jpg/webp等格式,详情参考RawView的源码吧.
  • Captcha有N多的组合和配置,自行选择啦.

修改登陆页面

打开当前登陆表单所在的webapp/index.jsp页面, 在下述代码
密码 <input name="password" type="password" value="123456">
的后面加入

        <script type="text/javascript">
            function next_captcha() {
                $("#captcha_img").attr("src", "${base}/captcha/next?_=" + new Date().getTime()); 
            }
        </script>
        验证码<input name="captcha" type="text" value="">
        <img id="captcha_img" onclick="next_captcha();return false;" src="${base}/captcha/next"></img>

将登陆的ajax登陆成功回调方法修改为如下

                    success: function (data) {
                        if (data && data.ok) {

                            alert("登陆成功");
//                            location.reload();
                            location.href = "/user";  //跳转到用户列表
                        } else {
                            alert(data.msg);
                        }
                    }

修改登陆方法

打开UserModule, 将login方法修改为

    @At
    @Filters // 覆盖UserModule类的@Filter设置,因为登陆可不能要求是个已经登陆的Session
    public Object login(@Param("username")String name, 
            @Param("password")String password, 
            @Param("captcha")String captcha,
            @Attr(scope=Scope.SESSION, value="nutz_captcha")String _captcha,
            HttpSession session) {
        NutMap re = new NutMap();
        if (!Toolkit.checkCaptcha(_captcha, captcha)) {
            return re.setv("ok", false).setv("msg", "验证码错误");
        }
        User user = dao.fetch(User.class, Cnd.where("name", "=", name).and("password", "=", password));
        if (user == null) {
            return re.setv("ok", false).setv("msg", "用户名或密码错误");
        } else {
            session.setAttribute("me", user.getId());
            return re.setv("ok", true);
        }
    }

页面测试

访问 http://127.0.0.1:8080 ,能正常显示验证码。
如果故意不填或写错会提示验证码错误,点击验证码会更换一个新的。