public class JwtFilter extends BasicHttpAuthenticationFilter {
/**
* 跨域支持
* @param request
* @param response
* @return
* @throws Exception
*/
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
return super.preHandle(request, response);
}
}
第一个问题是没使用请求头的token 出现了跨域问题 然后我开启了全局跨域
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* 基于Servlet的全局配置
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
System.out.println("处理全局跨域");
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("POST","GET","PUT","DELETE")
.maxAge(1800)
.allowCredentials(true)
.allowedHeaders("*")
.exposedHeaders("L-TOKEN");
}
}
但是 jwtFilter里面的方法始终都会出现跨域的问题 这是什么情况呢 该怎么解决 看网上说 只要用上面的就可以了 但发现不行
你可以这样试试看
@Configuration
public class GlobalCorsConfig {
/**
* 允许跨域调用的过滤器
*/
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
//允许所有域名进行跨域调用
config.addAllowedOrigin("*");
//允许跨越发送cookie
config.setAllowCredentials(true);
//放行全部原始头信息
config.addAllowedHeader("*");
//允许所有请求方法跨域调用
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
/**
* 跨域支持
* @param request
* @param response
* @return
* @throws Exception
*/
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
return super.preHandle(request, response);
}
上面14行代码删除,然后重新启动项目,
望采纳,谢谢
还需要在前端的配置文件加上这个axios.defaults.withCredentials = true;
而且不要用谷歌引擎
修改后还是会有这个问题 能不能给我具体讲讲 jwt拦截跨域和全局跨域要注意的点
看你用JWT应该是做前后端分离吧?shiro的认证,会对你的请求进行拦截,也就是logout、login 等url必须有对应的响应页面,应该是ShiroFilterFactoryBean的配置,没配置authc走RestAuthorizationFilter 过滤器,请参考如下代码:希望对你有帮助。
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 过滤器链定义映射
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
/*
* anon:所有url都都可以匿名访问,authc:所有url都必须认证通过才可以访问;
* 过滤链定义,从上向下顺序执行,authc 应放在 anon 下面
* */
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/i18n/**", "anon");
// 配置不会被拦截的链接 顺序判断,因为前端模板采用了thymeleaf,这里不能直接使用 ("/static/**", "anon")来配置匿名访问,必须配置到每个静态目录
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/html/**", "anon");
// 所有url都必须认证通过才可以访问
filterChainDefinitionMap.put("/**", "authc");
// 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了, 位置放在 anon、authc下面
filterChainDefinitionMap.put("/logout", "logout");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
// 配器shirot认登录累面地址,前后端分离中登录累面跳转应由前端路由控制,后台仅返回json数据, 对应LoginController中unauth请求
shiroFilterFactoryBean.setLoginUrl("/un_auth");
// 登录成功后要跳转的链接, 此项目是前后端分离,故此行注释掉,登录成功之后返回用户基本信息及token给前端
// shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权界面, 对应LoginController中 unauthorized 请求
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
Map<String,Filter> filters=shiroFilterFactoryBean.getFilters();
filters.put("authc", new RestAuthorizationFilter());
shiroFilterFactoryBean.setFilters(filters);
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
从你提供的报错信息判断,需要在18行处理option请求的地方加一个header:
httpServletResponse.setHeader("Access-control-Allow-Credentials", "true");
加上试试看,后续如果还有问题,把浏览器的报错信息提出来。
跨域是浏览器的问题,需要浏览器的报错信息才好定位。