三分钟教你用 Axios + AOP 实现全局登录拦截

371 阅读2分钟

前言

大家好,我是雪荷。在项目中有些功能需要用户先登录才可使用,我们不妨设置一个全局登录拦截器,强制用户登录,达到先登录再使用的效果。

 思路

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

代码实现

LoginInterceptor(登录拦截器):

/**
 * 登录拦截 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);
        }
    }
}

BusinessException:

public class BusinessException extends RuntimeException{
    private final int code;
    private final String description;

    public BusinessException(String message, int code, String description) {
        super(message);
        this.code = code;
        this.description = description;
    }
    public BusinessException(ErrorCode errorCode) {
        super(errorCode.getMessage());
        this.code= errorCode.getCode();
        this.description= errorCode.getDescription();
    }
    public BusinessException(ErrorCode errorCode, String description) {
        super(errorCode.getMessage());
        this.code= errorCode.getCode();
        this.description= description;
    }

    public int getCode() {
        return code;
    }

    public String getDescription() {
        return description;
    }
}

ErrorCode:

public enum ErrorCode {
    SUCCESS(0,"ok",""),
    PARAMS_ERROR(40000,"请求参数错误",""),
    NULL_ERROR(40001,"请求数据为空",""),
    NOT_LOGIN(40100,"未登录",""),
    NO_AUTH(40101,"无权限",""),
    FORBIDDEN(40301,"禁止操作",""),
    TOO_MANY_REQUEST(42900, "请求过于频繁", ""),
    SYSTEM_ERROR(50000,"系统内部异常","");
    /**
     * 状态码
     */
    private final int code;
    /**
     * 状态码信息
     */
    private final String message;
    /**
     * 状态码描述
     */
    private final String description;
    ErrorCode(int code, String message, String description) {
        this.code = code;
        this.message = message;
        this.description = description;
    }
    public int getCode() {
        return code;
    }
    public String getMessage() {
        return message;
    }
    public String getDescription() {
        return description;
    }
}

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

getLoginUser(获取登录用户):

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文件:

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就好了。

开源项目

厚米匹配

网址:厚米匹配系统

前端仓库:github.com/dnwwdwd/hom…

后端仓库:github.com/dnwwdwd/hom…

灵犀 BI

网址:鱼智能 BI

前端仓库:github.com/dnwwdwd/Lin…

后端仓库:github.com/dnwwdwd/Lin…