springboot配置拦截器,实现用户未登录不能访问其他页面
技术说明:
springboot:2.1.4.RELEASE
jQuery
Ajax
mysql:8.0.32
业务背景:
当我们没有登录的时候,如果访问其他页面,那就会造成信息泄露。所以,当用户没有登录的时候,访问其他页面的时候,必须自动跳转到用户登录页面
登陆页面
我们先弄个前端,实现一个用户登录页面,代码如下:
<form id="loginForm">
<div class="form-group">
<label for="username" class="block text-sm font-medium text-gray-700 mb-1">账号</label>
<input type="text" id="username" class="form-control" placeholder="请输入您的账号" required>
</div>
<div class="form-group">
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">密码</label>
<input type="password" id="password" class="form-control" placeholder="请输入您的密码" required>
<i class="fas fa-eye password-toggle" id="togglePassword"></i>
</div>
<button type="submit" id="signinSubmit" class="btn-login mt-4">
<i class="fas fa-sign-in-alt mr-2"></i>用户登录
</button>
</form>
给用户登录按钮做个单机时间,当用户点击的时候,获取输入框的值,传递给后端校验
$('#signinSubmit').click(function(){
if($('#username').val() === ''){
alert('用户名不能为空');
}else if($('#password').val() === ''){
alert('密码不能为空');
}
$.ajax({
type:"get",
url:"http://47.115.220.14:8081/user/login",
xhrFields: {
withCredentials: true
},
async:false,
data:{
"username":$("#username").val(),
"password":$("#password").val()
},
success:function (result) {
if (0 === result.code){
alert("登录成功");
//跳转到后台主页
window.location="main.html";
}else {
alert("登录失败,请核实用户名密码");
}
}
})
});
后端校验代码,接收/login登陆请求
@RequestMapping("/login")
@ResponseBody
public CommonReturnType login(@RequestParam("username") String username,
@RequestParam("password") String password,
HttpSession session){
//比对加密后的密码是否一致
String md5Password = MyMD5Util.md5Password(password);
UserAndPassword userAndPassword = userService.login(username);
if (userAndPassword.getAccountSwitch() == 1){//如果状态为1,说明账号开启,然后执行密码匹配
if (md5Password.equals(userAndPassword.getPassword())){
session.setAttribute("username",userAndPassword.getUsername());
session.setAttribute("state",userService.selectStateByUserName(username));
return CommonReturnType.success();
}
}
return CommonReturnType.fail("用户名或密码不正确");
}
如上代码,我们加入session会话管理,当用户登录的时候,获取用户的名称username,把这个用户名username交给session管理,那后续的任何操作,我们只要判断session会话中有没有这个用户名username即可,如果username为空,那就说明用户没有登录,此时跳转到登陆页面。
同理,也可以设置一个state状态,如果没有这个状态,我们可以判断不是管理员,可以限制对应的权限,比如不能删除等
那我们默认把所有页面都拦截,除了登陆页面,和管理员登录页面除外。默认只能登录,因为只有登录了,才能创建session会话,把username交给session管理。后续才能获取session中的username。
实现拦截器,拦截所有页面(排除用户登录,管理员登录页面)
创建一个拦截器
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在控制器处理方法调用之前执行
HttpSession session = request.getSession();
// 例如,获取或设置会话属性
String username = (String) session.getAttribute("username");
//System.out.println(username);
if (username == null) {
// 如果用户未登录,重定向到登录页面
response.sendRedirect("/");
return false; // 阻止控制器方法执行
}
return true; // 允许控制器方法继续执行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 在控制器方法执行之后,但渲染视图之前执行
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 在整个请求完成后执行,无论是否发生异常
}
}
如上,创建了一个拦截器,实现拦截器接口,重载了拦截器三个方法,拦截前,拦截中,拦截后,可以在对应方法中处理某些事情。我们这里很简单,直接在拦截器前拦截所有请求,看看有没有session会话的username,如果没有就返回index.html登陆页面。如果有,就释放拦截。如果拦截前找不到会话,那就重定向到登陆页面
拦截器创建好之后,还不能用,我们要注册拦截器,加入到springboot管理中。
注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**","/**/*","/*.html") // 指定拦截的路径模式
.excludePathPatterns("/index.html","/login-manager.html","/","/user/login","/user/manager/login","/exitlogin","/**/*.js","/**/*.css","/**/*.jpeg","/**/*.jpg"); // 排除的路径模式
}
}
如上,在注册拦截器类中,制定要拦截的请求,以及排除要拦截的文件类型,记住,把静态文件如js,jpg,css等排除掉,不然全部拦截了,就加载不出来页面了。另外排查登陆页面,不然怎么登陆啊
以上就可以了


浙公网安备 33010602011771号