homie匹配Axios+AOP实现全局登录拦截

思路

思路并不复杂,就是在执行每个Controller方法前执行getLoginUser方法判断登录用户是否是否为空,如果为空返回40100状态码,前端axios根据状态码跳转至登录页。因为在执行每个方法前都要执行getLoginUser方法(登录和注册接口除外),那么通过AOP实现是再方便不过了,并且强制用户在使用每个功能前要先登录。

代码实现

LoginInterceptor(登录拦截器):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
JAVA
/**
* 登录拦截 AOP
*/
@Aspect
@Component
public class LoginInterceptor {

@Resource
private UserService userService;

@Before("execution(* com.hjj.homieMatching.controller.*.*(..)) && " +
"!execution(* com.hjj.homieMatching.controller.UserController.userLogin(..)) && " +
"!execution(* com.hjj.homieMatching.controller.UserController.userRegister(..))")
public void beforeControllerMethodExecution() {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
if (userService.getLoginUser(request) == null) {
throw new BusinessException(ErrorCode.NOT_LOGIN);
}
}
}

注意:声明登录接口和注册接口不用执行beforeControllerMethodExecution方法。

getLoginUser(获取登录用户):

1
2
3
4
5
6
7
8
9
10
11
JAVA
public User getLoginUser(HttpServletRequest request){
if(request == null) {
return null;
}
Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
if(userObj == null) {
throw new BusinessException(ErrorCode.NOT_LOGIN);
}
return (User) userObj;
}

前端myAxios.ts文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
JAVASCRIPT
import axios from 'axios';

const isDev = process.env.NODE_ENV === 'development';

const myAxios = axios.create({
baseURL: isDev ? 'http://localhost:8080/api' : '线上地址',
})

myAxios.defaults.withCredentials = true; //设置为true

myAxios.interceptors.request.use(function (config) {
console.log('我要发请求啦');
return config;
}, function (error) {
return Promise.reject(error);
});

myAxios.interceptors.response.use(function (response) {
console.log('我收到你的响应啦');
console.log(response?.data.code);
// 未登录则跳转登录页
if (response?.data?.code === 40100) {
const redirectUrl = window.location.href;
window.location.href = `/user/login?=redirect=${redirectUrl}`;
}
return response.data;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});

export default myAxios;

测试:

启动前后端项目,发现无论点击任一 Tab 栏都会跳转登录页强制登录,至此全局登录拦截已实现。欢迎大佬们分享更好的实现方法。

前端代码没什么变化,主要添加一个LoginInterceptor就好了。