最近在做一个新项目,我用的是SpringBoot框架,采用前后端分离方式进行开发,这样在联调的时候就涉及到跨域的问题,通过网上找了很多资料参考,最后整理出来一份可以大家直接拿来使用的代码示例,希望对大家有更多的帮助,本文并不想讲太多的理论,网上讲理论的太多了,直接把代码分享给大家:
1、跨域配置类:
@Configuration
@Slf4j
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
// 允许cookies跨域
config.setAllowCredentials(true);
// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
config.addAllowedOrigin("*");
// #允许访问的头信息,*表示全部
config.addAllowedHeader("*");
// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
config.setMaxAge(18000L);
// 允许提交请求的方法,*表示全部允许
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowCredentials(true)
.maxAge(3600);
}
};
}
}
2、进行token校验,在前端进行登录等操作,会进行token的相关校验,针对跨域请求的POST请求,经过断点调试,发现首先会发送【OPTIONS】请求,然后通过之后才会发起真正的POST请求,代码如下:
@Configuration
@WebFilter(urlPatterns = { "/*" }, filterName = "tokenFilter")
@Slf4j
public class TokenFilter implements Filter {
@Autowired
private CSMJedisCluster cSMJedisCluster;
public static List<String> list = Lists.newArrayList();
static {
list.add("/csm-web/sys/verificationCode");
list.add("/csm-web/user/login");
list.add("/csm-web/user/logout");
list.add("/csm-web/user/SSORemould");
list.add("/csm-web/user/getSSOUserInfo");
list.add("/csm-web/call/reveiveRecord");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.setCharacterEncoding("UTF-8");
// 得到请求的URL
String requestURI = httpServletRequest.getRequestURI();
String method = httpServletRequest.getMethod();
log.info("------ TokenFilter获取请求接口地址 ------ :【{}】,请求方式:【{}】", requestURI, method);
// 直接放行
if (list.contains(requestURI)) {
log.info("------请求接口:【{}】,不做token校验,TokenFilter直接放行 ------ ",requestURI);
filterChain.doFilter(request, response);
return;
}
if ("OPTIONS".equals(method)) {
log.info("------ 请求接口:【{}】,请求方式:【{}】 不做校验,TokenFilter直接放行 ------ ",requestURI,method);
filterChain.doFilter(request, response);
return;
}
String clientId = httpServletRequest.getHeader("clientId");
String token = httpServletRequest.getHeader("token");
log.info("------ TokenFilter获取Header参数 ------:【clientId = {},token = {}】", clientId, token);
DataResponse responseResult = new DataResponse();
if(StringUtils.isEmpty(clientId) || StringUtils.isEmpty(token)){
responseResult.setReturnCode(RespCodeEnum.TOKEN_LOSE.getRespCode());
responseResult.setMessage("clientId或token参数值为空,请重新登录!");
handlePrintWriter(httpServletResponse,responseResult);
return;
}
String redisToken = cSMJedisCluster.get(JedisConst.CSM_TOKEN_DATA_CACHE_KEY + Integer.parseInt(clientId));
log.info("------ TokenFilter ------:【clientId = {},Redis获取该clientId的token = {}】", clientId,redisToken);
if(StringUtils.isEmpty(redisToken) ){
responseResult.setReturnCode(RespCodeEnum.TOKEN_LOSE.getRespCode());
responseResult.setMessage("token已过期,请重新登录!");
handlePrintWriter(httpServletResponse,responseResult);
return;
}
if(token.equals(redisToken)){
log.info("------ TokenFilter,请求的token与Redis获取的一致,直接放行------ ");
filterChain.doFilter(request, response);
return;
}else{
responseResult.setReturnCode(RespCodeEnum.TOKEN_LOSE.getRespCode());
responseResult.setMessage("token错误,请重新登录!");
handlePrintWriter(httpServletResponse,responseResult);
return;
}
}
@Override
public void destroy() {
}
public void handlePrintWriter(HttpServletResponse response, DataResponse result) throws IOException{
PrintWriter writer =null;
OutputStreamWriter osw = null;
try {
osw = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
writer = new PrintWriter(osw, true);
writer.write(JsonUtil.jsonFromObject(result));
writer.flush();
writer.close();
osw.close();
}catch (Exception e){
e.printStackTrace();
}finally {
if (null != writer) {
writer.close();
}
if (null != osw) {
osw.close();
}
}
}
}
可能大家的代码写法和思路不一样,可以做为一个参考,希望对大家有所帮助,那讲解的内容就很有意义。
来源:CSDN
作者:沉默成名
链接:https://blog.csdn.net/sinosoft12345/article/details/96172649