预检请求未通过访问控制检查 tomcat 10
Request to preflight doesn't pass access control check tomcat 10
我正在尝试设置一个 tomcat 服务器来接收来自 angular 网络应用程序的请求。一切正常,直到我开始尝试使用 DELETE 类型的请求。从我的调试中,我意识到问题出在我的过滤器中,该过滤器检查用户在尝试访问某些服务器资源时是否已经 session 并拒绝这些请求。
代码如下:
- 后端session过滤器:
public class SessionFilter extends HttpFilter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
var out = response.getWriter();
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json");
if (request.getSession(false) == null && !request.getRequestURI().equals("/login")) {
response.setStatus(401);
out.println(mapper.writerFor(ServletResponse.class).writeValueAsString(new ServletResponse("User must be logged in first!")));
return;
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
- 登录 servlet(提供 session 的那个)
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
sess = req.getSession(true);
sess.setMaxInactiveInterval(3600);
}
}
- 一些执行删除请求的 servlet
@WebServlet(urlPatterns = "/test")
public class TravelServlet extends HttpServlet {
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println(req.getParameter("test"));
}
}
- web.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>web.lab9.servlets.filters.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:4200</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,DELETE,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
现在在前端,使用 Angular,我这样调用请求:
this.http.delete<string>(this.url, {
params: new HttpParams().set('test', 'test'),
withCredentials: true
}).subscribe(result => {console.log(result);}, error => {console.log(error);});
每当删除请求到达服务器时,session 为空,并且我收到从 session 过滤器抛出的错误。据我了解,这是因为预检请求以及 headers 未在预检时设置的事实。有什么办法可以规避这个吗?我不允许使用除 HTTP servlet 和过滤器之外的任何东西。
此外,我是否也可以从 session 过滤器进行重定向?我能够在使用删除请求之前做到这一点,但自从我开始使用它以来,我只遇到了问题,因为与 get/post 请求一起工作的东西根本不适用于 delete/put/.. .
问题出在过滤器的顺序上。如果您想访问以下过滤器中的 cookie,cors 过滤器应始终位于第一个。该文档没有说明任何此类内容,所以我只是假设它无关紧要,但显然,它确实如此。
我正在尝试设置一个 tomcat 服务器来接收来自 angular 网络应用程序的请求。一切正常,直到我开始尝试使用 DELETE 类型的请求。从我的调试中,我意识到问题出在我的过滤器中,该过滤器检查用户在尝试访问某些服务器资源时是否已经 session 并拒绝这些请求。
代码如下:
- 后端session过滤器:
public class SessionFilter extends HttpFilter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
var out = response.getWriter();
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json");
if (request.getSession(false) == null && !request.getRequestURI().equals("/login")) {
response.setStatus(401);
out.println(mapper.writerFor(ServletResponse.class).writeValueAsString(new ServletResponse("User must be logged in first!")));
return;
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
- 登录 servlet(提供 session 的那个)
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
sess = req.getSession(true);
sess.setMaxInactiveInterval(3600);
}
}
- 一些执行删除请求的 servlet
@WebServlet(urlPatterns = "/test")
public class TravelServlet extends HttpServlet {
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println(req.getParameter("test"));
}
}
- web.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>web.lab9.servlets.filters.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:4200</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,DELETE,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
现在在前端,使用 Angular,我这样调用请求:
this.http.delete<string>(this.url, {
params: new HttpParams().set('test', 'test'),
withCredentials: true
}).subscribe(result => {console.log(result);}, error => {console.log(error);});
每当删除请求到达服务器时,session 为空,并且我收到从 session 过滤器抛出的错误。据我了解,这是因为预检请求以及 headers 未在预检时设置的事实。有什么办法可以规避这个吗?我不允许使用除 HTTP servlet 和过滤器之外的任何东西。
此外,我是否也可以从 session 过滤器进行重定向?我能够在使用删除请求之前做到这一点,但自从我开始使用它以来,我只遇到了问题,因为与 get/post 请求一起工作的东西根本不适用于 delete/put/.. .
问题出在过滤器的顺序上。如果您想访问以下过滤器中的 cookie,cors 过滤器应始终位于第一个。该文档没有说明任何此类内容,所以我只是假设它无关紧要,但显然,它确实如此。