I have a working application with a front end in vuejs and a backend in go. I'm in the process of adding the final features to the authentication and I'm running into an error.
When I try to add any http header to the vuejs request I get an error.
This is what I'm adding to the vue component:
http: {
headers: {
Authorization: 'Bearer 123'
}
}
And I'm getting a preflight error:
XMLHttpRequest cannot load http://localhost:8000/api/investments?limit=6. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
Now I know this is usually a server side problem but I am adding the response header resp.Header().Set("Access-Control-Allow-Origin", "*"). cors. If I remove the the http property in the vue object everything works fine. Its pretty bizzare I even tried handling the OPTIONS request with go but my handler for the api doesn't even get hit.
Ok so I found the answer it is a server problem the Authorization header was not authorized. So just add it as a middleware to allow for it.
c := cors.New(cors.Options{
AllowedHeaders: []string{"Origin", "Accept", "Content-Type", "Authorization"},
})
handler := c.Handler(router)
log.Fatal(http.ListenAndServe(":8000", handler))
I am using the rs/cors package
Related
I am using Beego/Golang as my backend and having an issue with No 'Access-Control-Allow-Origin' header when trying to fetch a URL from my domain. I searched on Google and put this in func main() but it still does not work, I still have the same error.
// (my own code) FilterUser is used to redirect users to login
// when they try to access some pages without logging in
beego.InsertFilter("/*", beego.BeforeExec, FilterUser)
// This is what I found on Google
beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
AllowAllOrigins: true,
AllowMethods: []string{"GET, POST, PUT, DELETE, OPTIONS"},
AllowHeaders: []string{"Origin"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
}))
You're setting both AllowCredentials and AllowAllOrigins. A casual examination of the source code of Beego's cors package indicates that, as a result, responses to preflight requests contain the following combination of headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
However, the Fetch standard (which defines how CORS works) instructs browsers to reject this combination—because honouring it would be very insecure. See this relevant passage of the MDN Web Docs about CORS:
When responding to a credentialed request, the server must specify an origin in the value of the Access-Control-Allow-Origin header, instead of specifying the "*" wildcard.
One way to fix the issue would be to allow, not all origins, but only the origin of your frontend; I used https://example.com as a placeholder below:
beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
AllowOrigins: []string{"https://example.com"}, // <---
// -snip-
AllowCredentials: true,
}))
I can't Enable CORS on my API Gateway instance, this is how it looks:
1. Settings:
2. Result:
I've tried a bunch of things like checking the DEFAULT 4XX and DEFAULT 5XX and manually inputting the Access-Control-Allow-Methods as suggested in some posts.
If I hover over the error I get: Invalid Response status code specified.
I'm able to GET using my browser but POST can only be done from Postman. My ReactJS website won't post either, throwing:
Access to XMLHttpRequest at <ENDPOINT> from origin <S3-REACT-BUCKET> has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I've read that I have my React app should send the CORS headers (haven't got to that) but I can't even Enable CORS in the API Gateway!
That was because No Method Response
You shouldn't manually go on the console to enable CORS. Instead follow this guide from the serverless framework.
In short:
set cors: true in your http event
return {'Access-Control-Allow-Origin': '*','Access-Control-Allow-Credentials': true} in your handler
I am trying to make a cross domain request from my React app (localhost:3000) to my Laravel PHP app (localhost:8000). I believe I have the back end set up to accept cross domain requests. I used this: https://github.com/barryvdh/laravel-cors
I seem to have all the parameters from this answer (https://stackoverflow.com/a/38087435/1555312), so I don't get why mine doesn't work. I actually see a 200 response + the expected body when I use the chrome console.
Here is the error I see in my console:
Failed to load http://localhost:8000/api/v1/upload-sessions: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Here is how my POST request looks like:
OPTIONS request:
POST request:
Expected response is sent, even though it complains about the CORS issue:
You need to set Access-Control-Allow-... on the response, not the request.
Once you remove that from the request, you probably won't need a pre-flight, so the OPTIONS request won't happen.
We are trying to implement Github oAuth in our app using Passport.js. If the user hits the endpoint by clicking an anchor tag/href, it works fine, but if we use a click handler to initiate an ajax request instead, we receive a CORS error from the Github server. Why?
Server side code:
app.get('/auth/github',
passport.authenticate('github', { scope: [ 'user:email' ] }));
app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/login' }),
function(req, res) {
console.log('Github authentication successful!');
res.redirect('/');
});
Client side code (we are using React):
--> Works:
<a href='/auth/github'>Contact</a>;
--> Does Not Work - CORS error:
handleContactAuth(event) {
$.ajax({
url: '/auth/github',
method: 'GET',
success: data => console.log( 'Contact Auth response: ', data),
error: err => console.log( 'Error connecting to GitHub.', err)
});
}
NOTE: This is a click handler on the React component and is functioning fine, as the ajax request is being triggered. I'm aware we're not handling the response currently, apart from just a console.log.
--> CORS Error we see on the Client side when using AJAX method instead of href:
XMLHttpRequest cannot load https://github.com/login/oauth/authorize? response_type=code&redirect_uri=ht…auth%2Fgithub%2Fcallback&scope=user%3Aemail&client_id=our_client_code. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Any ideas? Would appreciate any insights - many thanks.
CORS error is not an error returned by the server, but one triggered by the browser if the response doesn't contain HTTP headers signaling that cross-origin requests are allowed. The endpoint you are hitting obviously isn't designed to be accessed like this.
I had the same problem and I found that at least in Google Chrome XMLHttpRequest object is restricted to same origin policy. So you may need to stick to using an anchor tag.
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
Link: https://developer.chrome.com/extensions/xhr
In my angular2 app, I tried to make a cross domain ajax call. Although the call went through successfully, on angular2 side, the error callback was always triggered instead of the success callback. Here is the code:
this.http.post('http://localhost:3000/tasks/add', '["' + task + '"]', {headers: headers}).subscribe(
data => null,
err => alert("err"),
() => alert("succ")
);
In the browser console I saw this:
XMLHttpRequest cannot load http://localhost:3000/tasks/add. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
The server side was implemented in nodejs and it included the following to handle preflight
router.options('/add', (req, res, next) => {
console.log('!OPTIONS');
var headers = {};
// IE8 does not allow domains to be specified, just the *
// headers["Access-Control-Allow-Origin"] = req.headers.origin;
headers["Access-Control-Allow-Origin"] = "*";
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = false;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
res.writeHead(200, headers);
res.end();
});
The above server code was successfully executed, and client side did send the post request after the preflight options request.
My question is, what can I do in angular2 to make it trigger the success callback, which it should?
Update:
I am attaching a screenshot here and it was took in Chrome. The bottom part of it shows CORS error message, but top portion shows that the request went okay with 200. As a matter of fact it did go through, as I received both the options and post requests on the server side.
Update 2:
Tried express-cors on nodejs (server) side, still the same. (My initial code already handles preflight options request - the code can be found above in the original portion of this post. Unless there was a mistake in my original nodejs code, express-cors was not expected to change anything.)
Below is the code I tried with express-cors, basically the same as what's on its npm page:
var express = require('express');
var cors = require('express-cors')
var router = express.Router();
router.use(cors({
allowedOrigins: [
'*'
]
}))
Update 3:
Mystery solved! In my original code I only set the CORS headers in the options response, but not the response to the post request followed the options request. That appeared to still allow the whole process to complete at the application level - since the server side did get the post request and processed the data, but angular saw an error since the response did not include the proper headers. I modified my code to not only send back CORS headers in the options response, but also the post response, and now angular triggers the success callback.
In fact, there is a dedicated module for CORS with Express called cors. You can install it like this: npm install cors.
That said, there is nothing to do in the browser since everything is done under the hood for cross domain requests:
The browser sends the Origin header
Use simple or preflighted requests
Check the CORS response headers to see if your request can be executed
This link could help you to understand how CORS works within browsers: http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
So in short, it's a server issue not something in the Angular application. You can check the response content (headers) in the Chrome dev tools, tab Network to see that CORS headers are there in the response (both simple and preflighted).
Your error message doesn't look like the preflight request was successful. The preflight request is made by the browsers automatically before the actual request, if the preflight request results in an error, like in your case, the actual request isn't made at all.
Try this on the server instead:
headers["Access-Control-Allow-Origin"] = "http://localhost";