Skip to content
Advertisement

Angular app gets CORS error only in chrome

On my Angular app (Local host app with remote server), I get CORS error only in chrome, in Firefox, it works perfectly. Once it worked on both, but suddenly it stopped working on Chrome, I guess it’s related to a kind of update (I guess of chrome?? ) Ofcorse, uploading the app to the production server works on both browsers.

My server-side code is in Java (Servlets) and my CORSFilter looks like this:

public class CORSFilter implements Filter {
 
    /**
     * Default constructor.
     */
    public CORSFilter() {
        
    }
 
    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        
    }
 
    private final List<String> allowedOrigins = Arrays.asList("http://localhost:4200");
    
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        // Lets make sure that we are working with HTTP (that is, against HttpServletRequest and HttpServletResponse objects)
        if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;

            // Access-Control-Allow-Origin
            String origin = request.getHeader("Origin");
            LoggingService.writeToLog("call from origin: "+origin+", will be accepted? "+(allowedOrigins.contains(origin)||origin!=null), LogModule.WebAPI, LogLevel.Debug);
            
            response.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "");
            response.setHeader("Vary", "Origin");
            
            
            // Access-Control-Allow-Credentials
            response.setHeader("Access-Control-Allow-Credentials", "true");

            // Access-Control-Allow-Methods
            response.setHeader("Access-Control-Allow-Methods", "POST,HEAD, PUT, GET, OPTIONS, DELETE");
                       
            // Access-Control-Allow-Headers
            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-CSRF-TOKEN");
            if (request.getMethod().equals("OPTIONS")) {
                response.setStatus(HttpServletResponse.SC_ACCEPTED);
                return;
            }
     
        }

        chain.doFilter(req, res);
        
    }
}
    

Any ideas on how to make it working also in Chrome?

Advertisement

Answer

The problem is related to the last change of the Chrome browser CORS policy of SameSite cookies. For me, because I want to enable the CORS I had to add the SameSite=None parameters. Here is the updated code. Here is the post that helped me to verify what is needed to be done: Set cookies for cross origin requests

Please note that this code is valuable if you really need to enable the CORS option. This is a big decision.

public class CORSFilter implements Filter {
 

 
    private final List<String> allowedOrigins = Arrays.asList("http://localhost:4200");
    
    private final String SESSION_COOKIE_NAME = "JSESSIONID";
    private final String SESSION_PATH_ATTRIBUTE = ";Path=";
    private final String ROOT_CONTEXT = "/";
    private final String SAME_SITE_ATTRIBUTE_VALUES = ";HttpOnly;SameSite=None;Secure";
 
    
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        // Lets make sure that we are working with HTTP (that is, against HttpServletRequest and HttpServletResponse objects)
        if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;

            // Access-Control-Allow-Origin
            String origin = request.getHeader("Origin");
            LoggingService.writeToLog("call from origin: "+origin+", will be accepted? "+(allowedOrigins.contains(origin)||origin!=null), LogModule.WebAPI, LogLevel.Debug);
            
            response.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "");
            response.setHeader("Vary", "Origin");
            String requestUrl = request.getRequestURL().toString();
            
            // Access-Control-Max-Age
            //response.setHeader("Access-Control-Max-Age", "3600");

            // Access-Control-Allow-Credentials
            response.setHeader("Access-Control-Allow-Credentials", "true");

            // Access-Control-Allow-Methods
            response.setHeader("Access-Control-Allow-Methods", "POST,HEAD, PUT, GET, OPTIONS, DELETE");
            
            /*
            This the code that i added to the code to use SameSite=None Cookie
            */
            boolean isResourceRequest = requestUrl != null ? StringUtils.isNoneBlank(allowedOrigins.stream().filter(s -> requestUrl.contains(s)).findFirst().orElse(null)) : null;
            if (!isResourceRequest) {
                Cookie[] cookies = ((HttpServletRequest) request).getCookies();
                if (cookies != null && cookies.length > 0) {
                    List<Cookie> cookieList = Arrays.asList(cookies);
                    Cookie sessionCookie = cookieList.stream().filter(cookie -> SESSION_COOKIE_NAME.equals(cookie.getName())).findFirst().orElse(null);
                    if (sessionCookie != null) {
                        String contextPath = request.getServletContext() != null && StringUtils.isNotBlank(request.getServletContext().getContextPath()) ? request.getServletContext().getContextPath() : ROOT_CONTEXT;
                        response.setHeader("Set-Cookie", sessionCookie.getName() + "=" + sessionCookie.getValue() + SESSION_PATH_ATTRIBUTE + contextPath + SAME_SITE_ATTRIBUTE_VALUES);
                    }
                }
            }
            
           /*
            End of new code
           */
            
            // Access-Control-Allow-Headers
            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-CSRF-TOKEN");
            if (request.getMethod().equals("OPTIONS")) {
                response.setStatus(HttpServletResponse.SC_ACCEPTED);
                return;
            }
     
        }

        chain.doFilter(req, res);
        
    }
    
 
 
}
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement