最近在做一個新項目,我用的是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();
}
}
}
}
可能大家的代碼寫法和思路不一樣,可以做爲一個參考,希望對大家有所幫助,那講解的內容就很有意義。