Reputation: 711
I am sending an ajax request from host(http://abc.com.au) to the spring cloud API gateway running on host http://localhost:8081 .
jquery AJAX request code.
SimplifiedAdoptionBulkUpload.jsp
setCookie("username", 'abc', 30);
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "http://localhost:8081/api/v1/users/bulkUpload",
xhrFields: {
withCredentials: true
},
data: newData,
processData: false,
contentType: false,
crossDomain: true,
cache: false,
timeout: 600000,
success: function (data) {
.....
},
error: function (e) {
$('#btnSubmit').prop("disabled", false);
$('#txtMessage').text('Error Occured');
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.setRequestHeader('Access-Control-Allow-Credentials', 'true');
xhr.setRequestHeader('Access-Control-Allow-Headers', "Origin,Cookie,X-Requested-With, Content-Type, Accept, Authorization");
$('body').addClass("loading");
}
});
spring cloud gateway cors configuration.
@Configuration
public class PreFlightCorsConfiguration {
private static final String ALLOWED_HEADERS = "Origin,Cookie,X-Requested-With, Content-Type, Accept, Authorization";
private static final String ALLOWED_METHODS = "*";
private static final String ALLOWED_ORIGIN = "http://abc.com.au";
private static final String ALLOWED_EXPOSE = "*";
private static final String MAX_AGE = "3600";
@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = ctx.getResponse();
HttpHeaders headers = response.getHeaders();
headers.set("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
headers.add("Access-Control-Max-Age", MAX_AGE);
headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
headers.add("Access-Control-Allow-Credentials", "true");
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(ctx);
};
}
}
I am getting the below error in the chrome console.
SimplifiedAdoptionBulkUpload:1 Access to XMLHttpRequest at 'http://localhost:8081/api/v1/users/bulkUpload' from origin 'http://abc.com.au' has been blocked by CORS policy: Request header field access-control-allow-credentials is not allowed by Access-Control-Allow-Headers in preflight response.
Updates:
i removed this line from ajax request.
xhr.setRequestHeader('Access-Control-Request-Headers', "Origin,Cookie,X-Requested-With, Content-Type, Accept, Authorization");
i am setting two cookies(accces_token,refresh_token) to cookies in jsp and servlet filter.
public class AdminSecurityFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
boolean error = false;
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
request.setCharacterEncoding("UTF-8");
if(authenticated) {
String accessToken = getUserAccessToken(userStr,passStr);
if(!accessToken.isEmpty()) {
Cookie cookie = new Cookie("access_token", accessToken);
cookie.setPath("/");
//cookie.setHttpOnly(true);
//cookie.setDomain("localhost");
//TODO: When in production must do cookie.setSecure(true);
cookie.setMaxAge(3600);
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");
response.addCookie(cookie);
}
if(!refreshToken.isEmpty()) {
Cookie cookie = new Cookie("refresh_token", refreshToken);
cookie.setPath("/");
//cookie.setHttpOnly(true);
//cookie.setDomain("localhost");
//TODO: When in production must do cookie.setSecure(true);
cookie.setMaxAge(10000);
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");
response.addCookie(cookie);
}
}
}
also in jsp file i set value cookie using jquery.
function setCookie(cname,cvalue,exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
setCookie("username", 'Nirangaa', 30);
but these cookie values(username,refresh_token,access_token) are missing in headers in spring cloud gateway. why AJAX request are not sending cookies values appended in post request to apigteway side. @T.J. Crowder appreciate if you can explain why this is happening
@Component
public class AccessTokenCheckingGlobalFilterPre extends AbstractGatewayFilterFactory<AccessTokenCheckingGlobalFilterPre.Config> {
public AccessTokenCheckingGlobalFilterPre() {
super(AccessTokenCheckingGlobalFilterPre.Config.class);
}
@Override
public GatewayFilter apply(AccessTokenCheckingGlobalFilterPre.Config config) {
return (exchange, chain) -> {
Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
ServerHttpRequest request = null;
if (route != null) {
request = exchange.getRequest();
**//[Host:"localhost:8081", Connection:"keep-alive", Content-Length:"7391", Accept:"*/*", Access-Control-Allow-Credentials:"true", Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiamFjcGx1c19yZXNvdXJjZSJdLCJFeHBpcmVzSW4iOjM1OTksInVzZXJfbmFtZSI6Im5zYW5kYXJ1d2FAd2lsZXkuY29tIiwic2NvcGUiOlsiUkVBRCxXUklURSJdLCJleHAiOjE2MTUxOTQwNjIsInVzZXJOYW1lIjoibnNhbmRhcnV3YUB3aWxleS5jb20iLCJhdXRob3JpdGllcyI6WyJST0xFX0FkbWluaXN0cmF0b3IiLCJST0xFX3RlYWNoZXIiLCJST0xFX3NjaGFkbWluIiwiUk9MRV9zdHVkZW50Il0sImp0aSI6IjBkMjQ3ZjJkLTg0NjgtNDUwYS04NjI3LTAzOGI4ZmRlZjQ2MCIsImNsaWVudF9pZCI6ImphY3BsdXMifQ.GT0ayX01TO0fNY834n5_vXsqmt2P3s2C7hfMH-_FLvsNT-p9uIj5i0U66ZdouDUaL9xu1iy4wdfxLexfvilwnO10fTX5I0U7DHqHQetLUwCJOhET0hN-PyFcJRe7k3C3BUe8f7iuDd6Y4VbLCYTTpp4KSjWcS5fv-BTrvTvktwtkq5oFK2iCtPS6JwqPcFsvt2MYNi9UlGFeik_a-iyuTTa7xf7VgL2XFnGqcu3bOTUNxj4AhG91YL5har3OnFTbZnKFxVWykEz7MJFSXzmhmSS5rNYAbC5FBg65VFmzD0j9G4j1xPODxmLEEeE2Qj5FSe6VTnEZIiFHTLd27IuYyA", User-Agent:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36", Origin:"http://abc.com.au", Content-Type:"multipart/form-data; boundary=----WebKitFormBoundaryV5bORQSNHAa3kxFR", Referer:"http://admin.jacplus.com.au/admin/SimplifiedAdoptionBulkUpload", Accept-Encoding:"gzip, deflate, br", Accept-Language:"en-US,en;q=0.9"]**
HttpHeaders headers = request.getHeaders();
List<String> authorizationHeader = headers.get(HttpHeaders.AUTHORIZATION);
String value = authorizationHeader.get(0);
MultiValueMap<String, HttpCookie> cookies = request.getCookies(); /// nulll
}
return chain.filter(exchange.mutate().request(request).build());
};
}
Upvotes: 0
Views: 2040
Reputation: 1074385
The Access-Control-Allow-XYZ
headers are response headers, not request headers. Remove them from your $.ajax
call. You may want the Access-Control-Request-XYZ
header, e.g.:
xhr.setRequestHeader('Access-Control-Request-Headers', "Origin,Cookie,X-Requested-With, Content-Type, Accept, Authorization");
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^
That's a valid request header. (There's no Access-Control-Request-Credentials
header listed in the CORS spec, though, so your other line adding a Access-Control-Allow-Credentials
header should just be removed.)
More generally, any header in the request has to be allowed by your response's Access-Control-Allow-Headers
value, and yours didn't have that in it. But the fix is to remove it from the request, not add it to the Access-Control-Allow-Headers
value.
See also: CORS specification
Upvotes: 1