Java结合SpringBoot拦截器实现简单的登录认证模块

Java结合SpringBoot拦截器实现简单的登录认证模块

之前在做项目时需要实现一个简单的登录认证的功能,就寻思着使用Spring Boot的拦截器来实现,在此记录一下我的整个实现过程,源码见文章底部。

1. 环境搭建

IntelliJ IDEA + Java8 + Spring Boot + Tomcat
我将之前项目中的登录模块抽离出来,单独放在了一个新建的Spring Boot项目中;
整个项目的主要结构如下:
项目结构

参考资料:使用IDEA创建Spring Boot项目

2. 代码详解

2.1 前端代码

之前项目里别的小伙伴已经写好了一个简单的登录框样式表(login.css)和一些image图,我这里就顺手拿来用了,希望哪天你见了眼熟别拍我…
login.vm代码:
注意前端传递给后端Controller的password值并不是用户实际输入的密码!
实际传递的是用户名 + 密码(统一小写)组合的字符串的md5信息值;
这样在前后台数据传递及后台数据保存时传递和保存的都不是用户的真实密码值,可以一定程度提升安全性及规避某些风险;

更多资料可参考:Web前端密码加密是否有意义


     
     
  1. <html>
  2. <head>
  3. <title>系统登录</title>
  4. <meta charset="utf-8"/>
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  6. <meta name="author" content="Dreamer-1">
  7. <meta name="renderer" content="webkit" />
  8. <link href="/css/login/login.css" rel="stylesheet">
  9. <script type="text/javascript" src="/js/login/jquery/jquery.min.js?v=20170207"></script>
  10. <script type="text/javascript" src="/js/login/md5/md5.js"></script>
  11. </head>
  12. <body>
  13. <form name="form1" method="post" action="/login" id="form1" onsubmit="return checkLogin();">
  14. <div id="main">
  15. <div class="wrapper">
  16. <div class="login-hd"></div>
  17. <div class="login-body">
  18. <div class="logo">
  19. <span class="icon-logo"></span>
  20. </div>
  21. <div class="box">
  22. <div class="login-item">
  23. <span class="icon-user"></span>
  24. <input name="username" type="text" id="username" class="login-input" tabindex="1" maxlength="50" placeholder="请输入用户名" />
  25. </div>
  26. <div class="login-item mt35">
  27. <span class="icon-pwd"></span>
  28. <input type="password" id="password" class="login-input" tabindex="2" maxlength="32" placeholder="请输入密码"/>
  29. <input type="hidden" id="hidePwd" name="password">
  30. </div>
  31. <div class="login-forget" style="visibility:hidden">
  32. <a href="#">忘记密码</a>
  33. </div>
  34. <input type="submit" name="Logon" value="登录" id="Logon" tabindex="3" class="login-btn" />
  35. <div class="login-bottom">
  36. <div class="msg" style="display:none;" >
  37. <span class="icon-err"></span>
  38. <span id="message"></span>
  39. </div>
  40. </div>
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. </form>
  46. <script type="text/javascript">
  47. // onsubmit值为true时,提交表单,否则显示错误信息
  48. // 生成用户名+密码组合的md5值,并设置传给后端的密码为该md5值
  49. function checkLogin() {
  50. var name = $("#username").val().toLowerCase();
  51. var pwd = $("#password").val().toLowerCase();
  52. if(name.trim()=="" || pwd.trim()=="") {
  53. $("#message").text("请输入用户名和密码");
  54. $('.msg').show();
  55. return false;
  56. }else {
  57. $('.msg').hide();
  58. }
  59. var md5info = name + pwd;
  60. $('#hidePwd').val(md5(md5info));
  61. //$("#password").val();
  62. return true;
  63. }
  64. </script>
  65. </body>
  66. </html>

welcome.vm代码
登录成功后显示welcome.vm页的内容,这个页面很简单:


     
     
  1. <h1 align="center">登录成功!!!</h1>
  2. <br>
  3. <h3><a href="/loginout"><font color="red">退出登录</font></a></h3>
2.2 后端代码

后端代码相较于前端要复杂一些,让我们来一一拆解;

2.2.1 程序入口

ManApplication.java是整个程序的主入口,因为其上打了@SpringBootApplication的注解
注意:Spring Boot项目在tomcat上部署运行时,ManApplication需要继承SpringBootServletInitializer
ManApplication.java代码:


     
     
  1. /**
  2. * @SpringBootApplication 注解标明该类是本程序的入口
  3. */
  4. @SpringBootApplication
  5. public class ManApplication extends SpringBootServletInitializer {
  6. @Override
  7. protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
  8. return application.sources(ManApplication.class);
  9. }
  10. public static void main(String[] args) {
  11. SpringApplication.run(ManApplication.class, args);
  12. }
  13. }
2.2.2 Controller

IndexViewController.java类里就是简单的URL映射;


     
     
  1. /**
  2. * Created with logindemo.
  3. * Author: dreamer-1
  4. * Email: zhong--lei@outllok.com
  5. * Date: 2018/5/13
  6. * Time: 下午2:58
  7. * Description:
  8. */
  9. @Controller
  10. public class IndexViewController {
  11. /**
  12. * 登录
  13. * @return
  14. */
  15. @GetMapping("/")
  16. public String index() {
  17. return "login";
  18. }
  19. /**
  20. * 欢迎页
  21. * @return
  22. */
  23. @GetMapping("/welcome")
  24. public String welcome() {
  25. return "welcome";
  26. }
  27. }

LoginViewController.java类接收前端传过来的username和password,进行简单的校验和重定向;
此处为了简单就只设置了一个正确的账号和密码用于校验,你后续使用时可以结合自己的实际需求来扩充整个校验逻辑(比如通过专门的表来存储用户登录信息等);
用户名和密码校验通过后会在当前会话的session中放入一个登录标识,以表示当前用户已经登录;在退出登录或会话超时时销毁该标识;


     
     
  1. /**
  2. * Created with logindemo.
  3. * Author: dreamer-1
  4. * Email: zhong--lei@outllok.com
  5. * Date: 2018/5/13
  6. * Time: 下午2:49
  7. * Description:
  8. */
  9. @Controller
  10. public class LoginViewController {
  11. // 预先设置好的正确的用户名和密码,用于登录验证
  12. private String rightUserName = "admin";
  13. private String rightPassword = "admin";
  14. /**
  15. * 登录校验
  16. *
  17. * @param request
  18. * @return
  19. */
  20. @RequestMapping("/login")
  21. public String login(HttpServletRequest request) {
  22. String username = request.getParameter("username");
  23. String password = request.getParameter("password");
  24. if (null == username || null == password) {
  25. return "redirect:/";
  26. }
  27. // 前端传回的密码实际为用户输入的:用户名(小写)+ 密码(小写)组合的字符串生成的md5值
  28. // 此处先通过后台保存的正确的用户名和密码计算出正确的md5值,然后和前端传回来的作比较
  29. String md5info = rightUserName.toLowerCase() + rightPassword.toLowerCase();
  30. String realPassword = DigestUtils.md5DigestAsHex(md5info.getBytes());
  31. if (!password.equals(realPassword)) {
  32. return "redirect:/";
  33. }
  34. // 校验通过时,在session里放入一个标识
  35. // 后续通过session里是否存在该标识来判断用户是否登录
  36. request.getSession().setAttribute("loginName", "admin");
  37. return "redirect:/welcome";
  38. }
  39. /**
  40. * 注销登录
  41. *
  42. * @param request
  43. * @return
  44. */
  45. @RequestMapping("/loginout")
  46. public String loginOut(HttpServletRequest request) {
  47. request.getSession().invalidate();
  48. return "redirect:/";
  49. }
  50. }
2.2.3 Interceptor

LoginInterceptor.java是整个登录认证模块中的核心类之一,它实现了HandlerInterceptor类,由它来拦截并过滤到来的每一个请求;它的三个方法能分别作用于每个请求的不同生命周期,你可以根据自己的需要来加入相应的处理逻辑;


     
     
  1. /**
  2. * Created with logindemo.
  3. * Author: dreamer-1
  4. * Email: zhong--lei@outllok.com
  5. * Date: 2018/5/13
  6. * Time: 下午2:58
  7. * Description:
  8. */
  9. public class LoginInterceptor implements HandlerInterceptor {
  10. /**
  11. * 在请求被处理之前调用
  12. * @param request
  13. * @param response
  14. * @param handler
  15. * @return
  16. * @throws Exception
  17. */
  18. @Override
  19. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  20. // 检查每个到来的请求对应的session域中是否有登录标识
  21. Object loginName = request.getSession().getAttribute("loginName");
  22. if (null == loginName || !(loginName instanceof String)) {
  23. // 未登录,重定向到登录页
  24. response.sendRedirect("/");
  25. return false;
  26. }
  27. String userName = (String) loginName;
  28. System.out.println("当前用户已登录,登录的用户名为: " + userName);
  29. return true;
  30. }
  31. /**
  32. * 在请求被处理后,视图渲染之前调用
  33. * @param request
  34. * @param response
  35. * @param handler
  36. * @param modelAndView
  37. * @throws Exception
  38. */
  39. @Override
  40. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  41. }
  42. /**
  43. * 在整个请求结束后调用
  44. * @param request
  45. * @param response
  46. * @param handler
  47. * @param ex
  48. * @throws Exception
  49. */
  50. @Override
  51. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  52. }
  53. }
2.2.4 Configuration

LoginConfiguration.java是另一个核心类之一,它继承自WebMvcConfigurerAdapter类,负责注册并生效我们自己定义的拦截器配置;
在这里要注意定义好拦截路径和排除拦截的路径;

WebMvcConfigurerAdapter其实还可以做很多其他的事,包括添加自定义的视图控制器等等,详见这里


     
     
  1. /**
  2. * Created with logindemo.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值