java - Spring Restful : Handling OPTIONS request

标签 java spring spring-mvc tomcat7 spring-rest

我们正在使用 Spring Restful、oAuth、MVC 服务器端,如果服务器和 Web 应用程序在同一台服务器上运行,它工作正常。

我们在不同域中运行服务器和 Web 应用程序,我们面临无效 session 错误。

当我们进行后调用时,浏览器发出 OPTIONS 请求,但立即后调用失败。

我们启用了 CORS 过滤器,因此 OPTIONS 调用返回 200,但它使当前 session 无效,因此下一个 post 调用失败。

我们没有发送 OPTION 请求,所以直到拦截器仍然是它的无效 session 时它才到达。

我们尝试了以下解决方案:

  • 分派(dispatch) OPTIONS 请求并在拦截器中处理它。它正在创建新 session 但无法持久存储它。所以还是失败了
  • 在查询参数中发送自定义访问 token header 和 session Cookie,但我们无法在 JavaScript 中访问 session cookie。

我试图避免根据 OPTIONS 请求创建新 session ,请告诉我们如何避免在 Spring 或 Tomcat 中。

我们还需要为混合移动应用程序支持此解决方案(因为它不支持 cookie)。

启用 CORS:

在 web.xml 中:

<filter>
    <filter-name>CORSFilter</filter-name>
    <filter-class>com.tip.uiux.service.framework.CORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在 CORSFilter.java 中

@Override
public void doFilter(ServletRequest req, ServletResponse res,
          FilterChain chain) throws IOException, ServletException {
         HttpServletResponse response = (HttpServletResponse) res;
         response.setHeader("Access-Control-Allow-Origin", "*");
         response.setHeader("Access-Control-Allow-Credentials", "true");
         response.setHeader("X-Frame-Options", "DENY");
         response.setHeader("Access-Control-Allow-Methods","POST, GET, HEAD, OPTIONS");
         response.setHeader("Access-Control-Allow-Headers",
           "Custom-Access-Token, Origin, Accept, Session-Alias, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
         //LOGGER.info("Request Filtered for Cross Origin Resource Sharing using CORSFilter with custom headers");
         chain.doFilter(req, res); 
}

最佳答案

您还应该在响应中添加相关的 header 。请在您的应用程序中使用以下 CORS 过滤器。

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
    @Autowired
    Environment environment;

    public CorsFilter() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;

        HttpServletRequest request = (HttpServletRequest) req;

        if (Arrays.stream(this.environment.getActiveProfiles()).anyMatch(env -> (env.equalsIgnoreCase("development")))) {
            response.setHeader("Access-Control-Allow-Origin", "http://dev.yourdomain.com");
        } else if (Arrays.stream(this.environment.getActiveProfiles()).anyMatch(env -> (env.equalsIgnoreCase("production")))) {
            response.setHeader("Access-Control-Allow-Origin", "https://www.yourdomain.com");
        } else {
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
        }


        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Authorization, X-Requested-With, Content-Type, Accept, Key");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}

请注意,过滤器还会向 header 添加一些域信息(对于开发和生产环境,默认为 localhost)。如果您想使用它们,您可以为这些部分提供您自己的域。

希望对你有帮助

关于java - Spring Restful : Handling OPTIONS request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45347718/

相关文章:

java - DAO 类方法命名

java - 如何防止未经授权的用户删除域模型中的对象?

java - 随机化顶点位置 JUNG

java - 共享数据和 session 的两个网络应用程序

java - AWS lambda/api网关不重定向

java - Spring - 必须至少存在一个 JPA 元模型

java - 从 KeycloakPrincipal 获取用户区域设置

javascript - Mongoose 从远程服务器获取外部数据

java - Hibernate 的旧版 org.hibernate.Criteria API 已弃用

java - Spring-MVC:通过名称查找映射详细信息