I run the exact same code on Android and Web by using Dio for sending requests and what I see is that my backend doesn't get my custom added headers when I send the request from browser, but everything works fine if I do the same from emulator.
CORS is correctly setup on my backend.
Dio dio = Dio();
dio.options.headers[HttpHeaders.authorizationHeader] = "Bearer $token";
final Response response = await dio.get("http://$host:$port/$path", queryParameters: {"searchText": searchQuery, "page": 0, "pageSize": 100});
Additional information
post request works fine, the header is only missing from get requests. Either I use the http or dio packages.
However I can see in my server logs the following line when I log out all the headers of the request:
headerName: access-control-request-headers
header: authorization
Has anyone seen something similar?
As it seems I had to enable cors in spring security separatelly.
httpSecurity.csrf().disable()
.cors().and()
.authorizeRequests()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/support/**").hasRole("SUPPORT")
.antMatchers("/**").permitAll()
.and().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter::class.java)
Once I did so everything started to work.
So to sum up,
I used my custom headers in other places those were handled by my global CorsFilter but headers related to spring-security like Authorization are handled by spring-security so cors has to be enabled there as well regardles if I added Authorization to my global CorsFilter or not.
Related
There is an api for authorization, I send a request using thunder client, everything seems to be ok, I get a token in response, but when I try to knock on the same link in the application itself using the dio library, I get an Http status error [301] in response, what could be the problem, I didn't really find an answer anywhere?
how do I send a request
final response = await _dio.post(
'http://someaddress.com/api/auth/login',
data: {"login": phone, "password": event.password},
);
Error:
Http 301 status code means that the link is not anymore available and new one is defined in Location header. The response looks like something like this.
HTTP/1.1 301 Moved Permanently
Location: https://foo.bar/foobar
Response headers in dio can be accessed by headers property.
I have this Lambda function that can be triggered by API Gateway configured with the Serverless framework. The error I get on Access to XMLHttpRequest at '<THE_ENDPOINT>' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response This is how I use Axios in the Next App:
const handleSignUp = async (email, password) => {
const response = await Axios.post(
`${API}/signup`,
{
email,
password,
},
{
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
}
);
console.log(response);
};
This is my serverless.yml config file. I have tried to enable CORS manually from API Gateway console, but this is what it looks like.. When I make request with POSTMAN, it works normally.
Access-Control-Allow-Origin doesn't belong on the request header. It belongs on the response from the server, not part of the request from the browser. Adding it to the request is trying to tell the server what origins are allowed, but it's the server's job to say from where it will accept requests.
The Preflight Response is a clue that it's erroring out on the Options method.
I believe it's failing because you are trying to pass a header to the Options method that it's not looking for / isn't allowed. Try removing that header from the axios request and adding it to the APIGW response instead.
Under the Options method, check the Method Response and make sure you have Access-Control-Allow-Origin added to the Response Headers. Still on the Options method, check the Integration Response Header Mappings and add your allowed origin '*' (or a specific domain).
Don't forget to deploy your changes and wait a few moments for the change to propagate before testing.
In my flutter web when I'm trying to show network image, I'm getting an error of CORS.
Access to XMLHttpRequest at 'https://my-network-image-url.jpg' from origin 'http://localhost:63785' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Its working properly in my Android/iOS Mobile Apps.
I already fetch same issue in my backend php api.
At that time adding headers in php file solve the issue.
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: X-Requested-With,content-type");
I'm confuse how to add header in image get request.
Sorry If I'm asking same question again.
But I could not find proper solution for this.
Thanks in Advance.
You can mock the calls from any other endpoint which allows all cross origins like I have used the following,
String allowCORSEndPoint = "https://api.allorigins.win/raw?url=";
And while making a call you can use a a variable like this,
import 'dart:html' as html;
http.Response response = await http.get(
Uri.parse(allowCORSEndPoint + url),
);
I am getting a preflight error 405: Method not allowed from the HERE API when I request autocomplete as per the documentation.
UPDATE 2:
I have since determined that Axios was adding my default.common authentication headers from my app's API client onto the HERE API client. Axios is supposed to keep those defaults separate per-client, but it seems that it doesn't ... at least not the version I have. I replaced the defaults with a per-client request interceptor and it worked fine. The request no longer triggers an OPTION pre-flight. No issue with HERE's API other than that it doesn't support OPTION method.
UPDATE:
The reason it fails is because HERE does not support the OPTIONS method, only the GET. So now the question is: Why does axios trigger an OPTIONS request when I don't set any headers? An XMLHttpRequest() based GET request does not trigger OPTIONS for the same URL. Something is happening with axios but I don't know what and I can't seem to investigate the headers that axios is sending.
ORIGINAL:
I've tried to find information about this error, as well as HTTP vs HTTPS. I haven't seen others having this problem so I feel like I must be making a simple error. The URL is generated correctly because it works when pasted directly into the browser for example.
const hereClient = axios.create({
baseURL: 'https://autocomplete.geocoder.api.here.com/6.2/'
})
async function searchHere (query) {
let searchTerms = query.split(' ').join('+')
let result = await hereClient.get('suggest.json', {
params: {
app_id: '<APPID>',
app_code: '<APPCODE>',
query: searchTerms
}
})
return processHereSearchResults(result.data)
}
The GET request fails on the OPTION preflight with a 405: Method not allowed. But if I paste the generated URL into a browser then it returns the expected results. For example:
https://autocomplete.geocoder.api.here.com/6.2/suggest.json?app_id=APPID&app_code=APPCODE&query=8131
returns:
{"suggestions":[{"label":"Česko, Brandýs nad Orlicí, 3123","language":"cs","countryCode":"CZE","locationId":"N . . .
Same result whether http or https.
I have since determined that Axios was adding my default.common authentication headers from my app's API client onto the HERE API client. Axios is supposed to keep those defaults separate per-client, but it seems that it doesn't ... at least not the version I have. I replaced the default header setting with a per-client request interceptor to set my authentication and it worked fine. The request no longer triggers an OPTION pre-flight. No issue with HERE's API other than that it doesn't support OPTION method.
Requirement : Our application needs to support same user opening our web application as separated session.
The problem is not how to use cookies in angular 2, but how can sever get cookie from HTTPServletRequest object when angular 2 application makes a rest call to server.
Implementation: Server side restful application has one filter to set user's browser session in cookie and then in HttpServletResponse. Angular client is making one call upon application bootstrap, which is going through server filter to set user's browser session in cookie.
Problem statement: angular client is making first rest call which goes through server filter to set the browser session cookie. When i open chrome developer tool, i do see that rest api response has "set-cookie" which has cookie set by server, but when i open the application tag in developer tool, i do not see any cookie set.
After that if I make any other rest call through angular application, it does not send the cookie in either request or request headers. Now, our application rest api depends on this cookie value to be present in HttpServletRequest and now it is failing.
Can someone please guide me here? I must have done something wrong on angular 2 application side, which i am not able to catch.
I have tried passing "withCredentials =true", but no change.
Another thing I noticed, if i make "GET" request, then i do see cookie in request header, but for "POST" request, I do not see anything for cookie.
Please advice.
server side code to set cookie
String uniqueId = RandomStringUtils.randomAlphanumeric(32);
Cookie userSessionCookie = new Cookie("userSessionId", uniqueId);
if (getDefaultDomain() != null) {
userSessionCookie.setDomain(getDefaultDomain());
}
httpServletResponse.addCookie(userSessionCookie); httpServletResponse.addHeader("Access-Control-Allow-Credentials", "true"); httpServletResponse.addHeader("access-control-allow-methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
httpServletResponse.addHeader("Access-Control-Allow-Headers", "Content-Type, token,withCredentials");
angular 2 post request which expects server to get cookie from HttpServletRequest
renderFF() {
//prepare renderFInput object
var fcRenderInput = {};
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers, withCredentials: true
});
this._http.post('/api/v1/render/feature/fc',fcRenderInput,options)
.subscribe((res) => {
console.log(res.json());
});
}
Just a suggestion if this is about only one browser and multiple tabs, in this case you can use the local storage while setting some flag in it. Also when you try to open the same application in the new tab. you check if the flag is there and user is trying to open the same web application in some other tab of the same browser. You also need to delete the local storage you had set after some point.
I hope if you can get some trick to solve this issue :)