springboot添加图片验证码(拦截器)

先说下验证码的最基本思路。首先在后端生成随机验证码,存入session。前端接收后端生成的验证码图片或随机字符,展示给用户。用户输入验证码,提交时发送到后台,与session中的验证码进行比较。下面代码是生成的图片验证码,简单一点的可以直接生成随机数,来直接代替生成图片验证码的代码块

启动类中加入

@Override
	public void addInterceptors(InterceptorRegistry registry){
        InterceptorRegistration ir=registry.addInterceptor(new Interceptor1());
        ir.addPathPatterns("/**");
        //下面的/*/是要放开的方法和页面。像登录页面、在登陆时连接数据库判断用户是否正确的方法等。跟登录页面有关的方法貌似必须放开!!!包括映射登录页的方法
        ir.excludePathPatterns("/admin/yzm","/user/judge","/admin/sess","/user/findName","/admin/login","/admin/image","/admin/image.jpg","static/**","/js/**","/html/**","/images/**","/css/**");

    }

在controller包下

新建一个class文件,在文件中加入以下代码(我也是直接复制的)

package com.example.controller;//路径就是这样的

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class Interceptor1 implements HandlerInterceptor {//注意继承类
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception{
        HttpSession session=request.getSession();
        Object ob=session.getAttribute("uname");//这个就是要验证的内容,如果name为空,就会被拦截
        if (ob!=null) {//如果不为空,返回true,可以正常访问
            return true;//return后的代码不会执行,else写不写无所谓
        }//从这往下
        	
        
        session.setAttribute("preurl",request.getRequestURI());
        StringBuffer url = request.getRequestURL();
        String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getServletContext().getContextPath()).append("/").toString();
        //response.sendRedirect(tempContextUrl);//从这往上,什么意思我没看(其实是看不太懂),直接复制...
        response.sendRedirect("/admin/login");//登录失败后要跳转的页面,我的是失败后直接跳转登录页面
        return false;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
           Object handler,ModelAndView model) throws Exception{
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
             Object handler,Exception ex) throws Exception{
    }

}

在其他控制类中

//这个是映射登录页面的方法,里面不需要任何操作就行
@RequestMapping("login")
	public String login() {
		return "/admin/login";
	}

//这块是生成验证码图片的,图片是代码生成的,不需要自己添加
@RequestMapping(value = "/yzm", method = RequestMethod.GET)
	public void yzm(HttpServletRequest request, HttpServletResponse response) throws IOException {
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");
		// 生成随机字串
		String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
		// 存入会话session
		HttpSession session = request.getSession(true);
		// 删除以前的
		session.removeAttribute("verCode");
		session.removeAttribute("codeTime");
		session.setAttribute("verCode", verifyCode.toLowerCase());//将生成的验证码存入session
		session.setAttribute("codeTime", LocalDateTime.now());
		// 生成图片
		int w = 100, h = 30;
		OutputStream out = response.getOutputStream();
		VerifyCodeUtils.outputImage(w, h, out, verifyCode);
	}


//对输入的验证码和生成的验证码进行比较的
@RequestMapping("judge")
@ResponseBody
public JSONObject judge(HttpServletRequest req) {
	JSONObject jsonObject = new JSONObject();
	HttpSession session = req.getSession();
		
	String yzm = (String) session.getAttribute("verCode");//获取自动生成的验证码
	//System.out.println("yzm:"+yzm);
		
	String iyzm = req.getParameter("iyzm").toLowerCase();//获取用户输入的验证码,toLowerCase()好像是将大写字母转小写吧,是为了输入验证码的时候不区分大小写
	//System.out.println("iyzm:"+iyzm);
		
	//对两个验证码进行判断
	if(!yzm.equals(iyzm) ) {//如果两个不相同,不再进行下面的操作
		jsonObject.put("num", "1");
		jsonObject.put("result", "验证码输入错误");
		return jsonObject;
	}else {
		String uname = req.getParameter("uname");//接收登录页输入的name,获取数据库数据进行验证
			
		session.setAttribute("uname", uname);//将输入的neme存入session
		User user = userService.findName(uname);//使用输入的uname进行查询,获取数据库中的name,如果查到数据,表示uname输入正确;查询为空,uname输入错误(我的实体类是user)
		//String power = user.getPower();//有事没事,输出一下,看看有没有毛病
		//String uid = user.getUid();//这个id应该是通过上面方法查出来后,从实体中获取的,可能是我其他地方用的,在这里没什么用
		//System.out.println(uid);
		if(user==null) {//如果查询结果为空,说明用户名不存在
			jsonObject.put("num", "2");
			jsonObject.put("result", "用户名不存在或输入有误");
			return jsonObject;
		}else {//不为空,uname输入正确,进行密码的验证
			String pwd = req.getParameter("pwd");
			//System.out.println(pwd);
			//System.out.println(user.getPwd());
			if(!user.getPwd().contentEquals(pwd)) {//密码不相同,contentEquals() 方法用于将此字符串与指定的 StringBuffer 比较(百度的)跟equals差不多
				jsonObject.put("num", "3");
				jsonObject.put("result", "密码输入有误");
				return jsonObject;
			}else {
				jsonObject.put("num", "4");
				jsonObject.put("result", "登录成功");
				return jsonObject;
			}
		}
		//System.out.println(uname);
	}
}

前端页面代码

<div class="field"><!-- css代码我没有,我是直接扒的模板,虽然没有css,界面不美观,但是胜在能实现效果嘛。autocomplete="off"这个是清楚input记录的,反正加上就完事了 -->
	<input autocomplete="off"
	type="text" class="input input-big" id="nul" name="code" v-model="yzm" placeholder="填写右侧的验证码" data-validate="required:请填写右侧的验证码" />
        <img id="img" src="/admin/yzm" onclick="change()" class="passcode" style="height: 43px; cursor: pointer;" />
</div>



<!-- js代码  -->
methods:{
		//根据输入的内容进行查询
		findAll:function(){
			//alert(vm.uname);
			if(vm.uname==""){//先在前端验证下是否为空,后端也要验证
				alert("请输入用户名");
			}else{
                //将输入的内容传到后端
				$.post("/user/judge",{uname:vm.uname,pwd:vm.pwd,iyzm:vm.yzm},function(data){
					
					if(data.num==4){//全部正确,跳转首页
						window.location.href="/admin/index";
					}else if(data.num==1){
						alert(data.result);
						change();//调用change(),实现验证码刷新
						//$("#nul").remove().val();
					}else{
						alert(data.result);
					}
						
				});
			}
		},
	},
//这个方法我是写在vue外面的
function change(){
    var img = document.getElementById("img"); 
    img.src = "/admin/yzm?date="+new Date();
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值