先说下验证码的最基本思路。首先在后端生成随机验证码,存入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();
}