解决方案一:
使用过滤器或者拦截器,在过滤器或者拦截器中判断用户是否已经完成登录,如果没有则跳转到登录页面。
代码实现:
1.创建自定义过滤器LoginCheckFilter
2.在启动类上加上注解 @ServletComponentScan(意思是开启组件扫描,这样才会扫描到过滤器)
3.完善过滤器的处理逻辑
后端代码如下:
/*
* 检查用户是否已经完成登录
* */
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符。用来进行路径比较
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//向下转型,转成http的形式
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1.获取本次请求的url
String requestURI = request.getRequestURI();
log.info("拦截到请求:{}",requestURI);
//定义不需要处理的请求路径
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};// **指backend文件夹下的资源,这些都是静态资源,不用处理,直接放行就可以
//2.判断本次请求是否需要处理(其实就是检查登录状态,就是看请求路径是否在urls里面)
boolean check = check(urls,requestURI);
//3.如果不需要处理,则直接放行
if(check){
log.info("本次请求{}不需要处理",requestURI);
filterChain.doFilter(request,response);
return;
}
//4.判断登录状态,如果已登录,则直接放行
if(request.getSession().getAttribute("employee") != null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request,response);
return;
}
log.info("用户未登录");
//5.如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
/*
* 路径匹配,检查本次请求是否需要放行
* */
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url,requestURI);
if(match){
return true;
}
}
return false;
}
}
前端代码:
// 响应拦截器
service.interceptors.response.use(res => {
if (res.data.code === 0 && res.data.msg === 'NOTLOGIN') {// 返回登录页面
console.log('---/backend/page/login/login.html---')
localStorage.removeItem('userInfo')
window.top.location.href = '/backend/page/login/login.html'
} else {
return res.data
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
}
else if (message.includes("timeout")) {
message = "系统接口请求超时";
}
else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
window.ELEMENT.Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
win.$axios = service
})(window);
解决方案二:路由导航守卫控制访问权限
如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面。
Vue——Index.js
export default router;
// 为路由对象,添加beforeEach导航守卫
router.beforeEach((to, from, next) => {
if(to.path ==='/register') return next()
if(to.path ==='/login') return next() //如果用户访问的登录页,直接放行
const tokenStr = window.sessionStorage.getItem('token')//从sessionStorage中获取保存的token值
if(!tokenStr) return next('/login')//没有token,强制跳转到登录页
next()
})