springboot filter 配置跨域信息

排查问题

由于认证是手动实现的,所以需要在filter中检测token是否合法,如果不合法就直接在filter中返回错误信息(json)

package com.carenmg.shangpu.filter;

import com.carenmg.shangpu.pojo.Admin;
import com.carenmg.shangpu.pojo.bo.JsonData;
import com.carenmg.shangpu.service.AdminService;
import com.sun.xml.internal.xsom.impl.Ref;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.rmi.server.ExportException;
import java.util.*;

@WebFilter(urlPatterns = {"/api/*"})
@Component
public class TokenFilter implements Filter {
    @Autowired
    private AdminService adminService;
    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("", "/login")));

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init filter");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //返回可以跨域的配置
        response.setHeader("Access-Control-Allow-Origin","*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        response.addHeader("Access-Control-Max-Age", "1800");//30 min
        //is login request?
        StringBuffer requestURL = request.getRequestURL();
        if (requestURL.toString().contains("/login") && request.getMethod().equals("POST")) {
            filterChain.doFilter(request, response);
        } else {
            //查找用户,存入session
            try {
                String token = request.getHeader("token");
                if (ObjectUtils.isEmpty(token)) {
                    throw new Exception("请求失败,请登录后重试");
                }
                Admin admin = adminService.findByToken(token);
                if (ObjectUtils.isEmpty(admin)) {
                    throw new Exception("登录信息已过期,请重新登录");
                }
                HttpSession session = request.getSession();
                session.setAttribute("user", admin);
                filterChain.doFilter(request, response);
            } catch (Exception e) {
                //need login first
                response.setHeader("Content-Type", "application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":1,\"msg\":\""+e.getMessage()+"\"}");
            }
        }
    }
}

但是在login的时候无论怎样都提示跨域问题
在这里插入图片描述
各种google、百度都没有解决问题,最后仔细观察发现这里有个提示has been blocked by CORS policy: Request header field token is not allowed by Access-Control-Allow-Headers in preflight response.,由于对跨域学习不够透彻,其实在配置response.setHeader("Access-Control-Allow-Headers", "x-requested-with,token");的是时候以为这样配置就可以了,但是由于请求中携带了token(过期的,存储在localStorage里面,每次请求都携带token),所以跨域失败了。

springboot配置跨域

  1. 在controller中配置跨域,可以直接设置注解@CrossOrigin;
@RestController("apiGroup")
@RequestMapping("api/group")
@CrossOrigin(origins = "http://localhost:8080")
public class GroupController {
	//...
}
  1. 在Application中配置@Bean
@MapperScan("com.carenmg.shangpu.mapper")
@SpringBootApplication
public class ShangpuApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShangpuApplication.class, args);
    }
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/*").allowedOrigins("*").allowedMethods("POST","GET","PUT","DELETE");
            }
        };
    }
}
  1. 在filter中配置(前面的)
  2. 单独的Component
public WebMvcConfigurer corsConfigurer() {
		return new WebMvcConfigurer() {
			@Override
			public void addCorsMappings(CorsRegistry registry) {
				registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:8080");
			}
		};
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值