为了更加深刻的理解Cookie与Session,写了个登录页面。
(关于Cookie与Session的区别)
https://blog.csdn.net/qq_36781505/article/details/88540985
环境如下:
- idea
- SpringBoot
- SpringMVC
- JQuery
1、其设计逻辑图如下
-
1、采用前后端分离的方式,当前端页面初始化的时候请求服务端,然后检查登录Cookie是否存在。若存在重定向到登录后的页面user.html
-
2、跳转到user.html,使用过滤器通过查看session验证是否登录过。
-
2、登录成功后会添加Cookie返回给客户端
-
3、返回验证码图片给前端的同时把验证码放入session中,登录时在服务端进行匹配。
-
4、请求user.html使用过滤器查看session验证是否登录过。
2、运行截图
第一次请求
登录后
请求index.html(为了查看Cookie,打了个断点)
然后直接重定向到user.html
清除cookie后
3、前端代码
前端页面就三个请求
- 1、初始化的时候发送Cookie(请求的时候浏览器会自动附上Cookie)
- 2、请求验证码图片
- 3、提交表单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="script/jquery-3.3.1.min.js"></script>
<script src="script/script.js"></script>
</head>
<script>
window.onload= function () {
$.ajax({
type: 'get',
dataType: 'text',
url: 'user/index',
success: function (data) {
var json= $.parseJSON(data);
if(json.code==200){
console.log(window.location.host+"/login/user.html")
window.location.replace("http://"+window.location.host+"/login/user.html");
}
}
})
};
$(function () {
$("#button1").click(
function () {
$.ajax({
type: 'POST',
dataType: 'text',
url: 'user/login',
data: $("#login_from").serializeArray(),
contentType: 'application/x-www-form-urlencoded',
success: function (data) {
window.location.replace("http://"+window.location.host+"/login/user.html");
}
})
}
);
});
</script>
<body>
<form id="login_from">
用户名<input name="username" type="text"><br/>
密码<input name="password" type="password"><br/>
验证码<input name="code" type="text" required><img src="/user/getImg">
</form>
<button id="button1">Login</button>
</body>
</html>
3、后端
1、处理页面初始化的请求,检查Cookie
@RequestMapping("/index")
@ResponseBody
public ApiResult index(HttpServletResponse res,HttpServletRequest req){
Cookie[]cookies=req.getCookies();
if(cookies!=null){
for (Cookie cookie:cookies){
if(cookie.getName().equals("username")){
log.info("========user login successfully by cookie");
//在Session中为设置登录标志
req.getSession().setAttribute("isLogon",true);
return ResultUtil.success();
}
}
}
return ResultUtil.error(ResultEnum.UNKONW_ERROR);
}
2、处理验证码请求
@RequestMapping("/getImg")
@ResponseBody
public ApiResult getImg(HttpServletResponse res,HttpServletRequest req) throws IOException {
HttpSession session=req.getSession();
Object[] objects=VerifyUtil.createImage();
BufferedImage image= (BufferedImage) objects[1];
//将验证码的内容放入Session
session.setAttribute("code", (String) objects[0]);
res.setContentType("image/jpeg");
ServletOutputStream out = res.getOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.flush();
return null;
}
3、登录验证(这里为了方便没有访问数据库)
@RequestMapping(value = "/login",method = RequestMethod.POST)
@ResponseBody
public ApiResult login(String username, String password, String code, HttpServletResponse resp, HttpServletRequest req){
HttpSession session=req.getSession();
log.info(code);
String vcode=session.getAttribute("code").toString();
//匹配验证码
if(code.equals(vcode)){
log.info("========vcode is true");
//匹配用户名与密码
if(username.equals("root")&&password.equals("000000")){
log.info("========user login successfully by password");
Cookie cookie = new Cookie("username", username);
//登录成功返回cookie
resp.addCookie(cookie);
req.getSession().setAttribute("isLogon",true);
return ResultUtil.success();
}else return ResultUtil.error(ResultEnum.LOGIN_ERR);
}else return ResultUtil.error(ResultEnum.VCODE_ERR);
}
4、过滤器(验证是否登录)
用户登录后的页面在/login目录下
@WebFilter(filterName = "LoginFilter",urlPatterns = "/login/*")
@Slf4j
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession(false);
if(null!=session){
//检查Session中是否存在isLogon
if(session.getAttribute("isLogon")!=null)filterChain.doFilter(servletRequest,servletResponse);
else response.sendRedirect("/index.html");
} else response.sendRedirect("/index.html");
}
...
}