前后端联调解决跨域问题
有很多种方法,比如设置允许cors资源共享技术、代理…这里用的是第一种cors
- 前端发送axios请求时要允许带着cookie凭证访问后端
// 我这里是在创建实例时就设置了
const instance: AxiosInstance = axios.create({
baseURL,
timeout,
withCredentials: true
});
- 后端使用配置类开启CORS
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 覆盖所有请求
registry.addMapping("/**")
// 允许发送 Cookie
.allowCredentials(true)
// 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突)
.allowedOriginPatterns("*")
// .allowedOrigins("http://localhost:5002")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("*");
}
}
捕获认证时异常并自定义异常
-
昨天(7.22)搞了一个@RestControllerAdvice + @ExceptionHandler 实现的全局异常处理器,专门处理AuthenticationException这种认证时异常,结果今天发现,如果用户未登录时访问需要登陆才能访问的资源,只会报403,全局异常处理器根本捕获不了,原因是
全局异常处理器只能捕获Controller层的异常
,而
未登录的异常是在过滤器链中被抛出的,根本就捕获不了
,搞来搞去,得去写一个AuthenticationEntryPoint的实现类去专门处理认证时异常,只要认证过程中一报错,就会进这个接口的commence方法,无论这个异常是在过滤器链中还是控制层中被抛出。
@Slf4j
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
log.error("CustomAuthenticationEntryPoint认证时异常", authException);
BaseResponse<?> errorResponse = ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "请重新登陆");
// 设置响应数据格式为JSON
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
try {
// 将错误信息转为JSON格式并写入响应中
response.getWriter().write(JSONUtil.toJsonStr(errorResponse));
response.getWriter().flush();
} catch (IOException ioException) {
// 异常处理失败时的处理逻辑
log.error("CustomAuthenticationEntryPoint异常处理失败:", ioException);
}
}
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(new CustomAuthenticationEntryPoint());
}
授权时异常
- 还是在全局异常处理器中捕获和处理,因为SpringSecurity中的认证原理是通过AOP来实现的,AOP也属于控制层的东西,所以,当授权时出现异常,全局异常处理器也能够捕获
//捕获授权时异常
@ExceptionHandler(AccessDeniedException.class)
public BaseResponse<?> accessDeniedExceptionHandler(AccessDeniedException e) {
log.error("AccessDeniedException", e);
return ResultUtils.error(ErrorCode.FORBIDDEN_ERROR, e.getMessage());
}
版权声明:本文为weixin_63742275原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。