Hello everyone please help me about my CORS problem
Im creating an API request from another domain my code below with an error,
var headers = {
host: host,
path: url + instance + '?action=reset',
method: 'POST'
};
var request = https.request(headers, function (response) {
logger('OCICompute', 'reset', 'INSTANCE', 'Got response from OPCAPI:' + response.statusCode);
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Methods", "OPTIONS, TRACE, GET, HEAD, POST, PUT");
res.header("Access-Control-Expose-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
if (response.statusCode === 200) {
response.on('data', function (body) {
var data = JSON.parse(body);
res.json(data);
});
} else {
logger('OCICompute', 'reset', 'ERROR', 'stop fail');
res.json({'result': 'Fail'});
}
});
code above is on my module
and I have option in my main.
app.opts('/\.*/', function(req, res, next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Methods", "OPTIONS, TRACE, GET, HEAD, POST, PUT");
res.header("Access-Control-Expose-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.send(200);
});
When I access this rest im getting this
405 error method not accepted and only got this
Host: api Url
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: ja,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:3000/?root=compute
Authorization: Bearer Token
Origin: http://localhost:3000
Connection: keep-alive
Allow: OPTIONS
Connection: keep-alive
Content-Length: 58
Content-Type: application/json
Date: Tue, 24 Apr 2018 02:05:47 GMT
Server: LBAAS
Strict-Transport-Security: max-age=31536000; includeSubdomains;
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
I have another code which do exactly what I expected, the only difference is im using GET method. Above with error is POST.
var headers = {
host: host,
path: url + instance + '?action=reset',
method: **'GET'**
};
And here is the result
>
Host: api Url User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0)
> Gecko/20100101 Firefox/52.0 Accept: */* Accept-Language:
> ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate, br Referer:
> http://localhost:3000/?root=compute Authorization: Bearer Token
> Origin: http://localhost:3000 Connection: keep-alive
>
> Access-Control-Allow-Credentials: true Access-Control-Allow-Headers:
> Content-Type, Authorization, Accept, X-Requested-With
> Access-Control-Allow-Methods: OPTIONS, TRACE, GET, HEAD, POST, PUT
> Access-Control-Allow-Origin: http://localhost:3000
> Access-Control-Expose-Headers: Content-Type, Authorization, Accept,
> X-Requested-With Connection: keep-alive Content-Length: 2556
> Content-Type: application/json Date: Tue, 24 Apr 2018 02:05:57 GMT
> Server: LBAAS Strict-Transport-Security: max-age=31536000;
> includeSubdomains; X-Content-Type-Options: nosniff X-XSS-Protection:
> 1; mode=block
Here is my code on client side
self.stopButtonClick = function (event) {
console.log("停止ボタンが押されました");
var headers = {"Authorization": 'Bearer ' + self.ociComputeToken._latestValue};
$.ajax({
url: url,
type: "GET",
async: true,
headers: headers
}).done(function (data, textStatus, jqXHR) {
if (data.result !== 'Fail') {
self.compartmentHandler(self.compartmentId());
} else {
self.stopButtonClick(event);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log('サービスエラー');
self.stopButtonClick(event);
});
};
I just solve this one, and the problem is the url that im accessing is not correct, But then I got another error which is 502 bad gateway, GET is working fine, but what should I do when POST method is use?
Related
I have following HTTP response:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, authorization, content-type, origin, x-requested-with, user-agent, access-control-allow-origin, crossdomain, access-control-allow-credentials, x-requested-with
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH
Access-Control-Allow-Origin: https://speechifai-dashboard-fe.herokuapp.com
Access-Control-Max-Age: 600
Connection: keep-alive
Content-Length: 35
Content-Type: application/json; charset=utf-8
Date: Fri, 25 Feb 2022 05:52:17 GMT
Server: Cowboy
Set-Cookie: sessionIdSp=+5BtM+x+ZZ262Vs362qgUUmJE8PXd12G+AwMSdH14JQ=; Path=/; Secure; HttpOnly; SameSite=Lax
Link is here, you can try: https://speechifai-dashboard-fe.herokuapp.com/createPost
So frontend connect to backend, backend sends cookie, but I can not see under Cookies, why? What do I miss?
I have a Vapor backend:
It has following setting, what is wrong?
app.middleware.use(CORSMiddleware(configuration: .init(
allowedOrigin: .originBased,//.originBased,
allowedMethods: [.GET, .POST, .PUT, .OPTIONS, .DELETE, .PATCH],
allowedHeaders: [.accept, .authorization, .contentType, .origin, .xRequestedWith, .userAgent, .accessControlAllowOrigin, .init("crossDomain"), .accessControlAllowCredentials, .xRequestedWith],
allowCredentials: true
)), at: .beginning)
// Change the cookie name to "foo".
app.sessions.configuration.cookieName = cookieName
// Configures cookie value creation.
app.sessions.configuration.cookieFactory = { sessionID in
print("sessionID.string: \(sessionID.string)")
return .init(string: sessionID.string, isSecure: true, isHTTPOnly: true)
}
Calling here backend from React frontend:
axios({
method: "post",
url: "registerEmail",
data: {},
headers: {
"Content-Type": "application/json",
crossDomain: true,
},
})
.then((res) => {
dispatch(setGetUser(res.data));
})
.catch((err) => console.error(err));
I'm having trouble with the CORS policy problem.
The project is very simple. I'm using the Sendgrid for sending e-mail.
I implemented frontend and backend for this tiny project. In backend, Sendgrid sending mail function is used.
I tested in local, it works fine. After I deployed the project, I got CORS issue.
This is the Error messages.
Access to fetch at 'https://mailsender-api.xxxxxx.xxx/sendmail' from origin 'https://mailsender-xxxxx.xxxxxx.xxx' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
POST https://mailsender-api.xxxxxx.xxx/sendmail net::ERR_FAILED
In frontend I separate fetch function
Fetch.tsx
export const fetchPost = async ({ endpoint, data }: any) => {
return fetch(`https://mailsender-api.xxxxxx.xxx/${endpoint}`, {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
mode: "cors",
});
};
and different file calls the fetch function
const handleClick = async (
email: string,
subject: string,
intention: string
) => {
if (email === "" || intention === "") {
alert("Please fill out all fields");
} else if (!validateEmail(email)) {
alert("Invalid Email address");
} else {
const fetchOption = {
endpoint: `sendmail`,
data: {
email,
subject,
intention,
},
};
const result = await fetchPost(fetchOption);
if (result.ok) {
return history.push("/complete");
}
}
}
Below are backend code. I separate send mail function.
server.js
import cors from "cors";
import express from "express";
import { sendmail } from "./sendmail";
const router = express.Router();
const server = express();
server.use(
cors({
methods: ["GET", "POST", "OPTIONS"],
allowedHeaders: ["Content-Type", "Access-Control-Allow-Origin", "Accept"],
origin: "*",
credentials: true,
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
})
);
server.use(express.json({ type: ["application/json"] })); // for parsing application/json
server.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
router.post("/sendmail", sendmail);
router.options("*", cors());
server.use(router);
server.listen(4000, function () {
console.log("app is listening");
});
export { router };
export default server;
when post requests comes in, sendmail function is invoked.
sendmail.js
import { sendScheduledMail } from "./config";
export const sendmail = async (req, res) => {
let data = {
address: req.body.email,
subject: req.body.subject,
content: req.body.intention,
};
try {
await sendScheduledMail(data.address, data.subject, data.content);
return res.end();
} catch (error) {
console.log(error);
}
};
Below is config.js file
import sgMail from "#sendgrid/mail";
import dotenv from "dotenv";
import "../.env";
dotenv.config();
export const sendScheduledMail = (address, subject, content) => {
let date = Math.round(new Date("June 29, 2020 12:37:00").getTime() / 1000);
let tempDate = Math.round(new Date().getTime() / 1000);
const email = {
from: "CBLM#CBLM.com",
to: address,
subject: subject,
html: `<p>${content}</p>`,
send_at: tempDate,
};
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
return sgMail.send(email);
};
I deployed in Vercel.com. I asked about this problem, they said, it is codebase problem, so they have nothing to do. I searched for the solution, and I followed all they suggest, but it didn't work. Please help me.
------------------------UPDATED----------------------------------------
I deleted "Access-Control-Allow-Origin": "*", but it is not working.
I found out that Vercel has their own configure file ('now.json'). I added some headers, then I got something else.
now.json file
{
"routes": [
{
"headers": {
"Access-Control-Allow-Origin": "https://mailsender-delta.xxxxxx.xxx",
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "POST, OPTIONS, HEAD",
"Access-Control-Allow-Headers": "Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Allow-Origin, Content-Type",
"Access-Control-Allow-Credentials": "true"
},
"src": "/.*",
"dest": "/server.js"
}
]
}
I got POST https://mailsender-api.xxxxxx.xxx/sendmail net::ERR_ABORTED 405
Below is the request header
> General
Request URL: https://mailsender-api.xxxxxx.xxx/sendmail
Request Method: OPTIONS
Status Code: 204
Remote Address: 76.76.21.21:443
Referrer Policy: no-referrer-when-downgrade
> Response Headers
access-control-allow-credentials: true
access-control-allow-headers: Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Allow-Origin, Content-Type
access-control-allow-methods: OPTIONS, GET, HEAD
access-control-allow-origin: *
cache-control: s-maxage=0
date: Fri, 03 Jul 2020 23:20:50 GMT
server: Vercel
status: 204
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-vercel-cache: HIT
x-vercel-id: iad1::frndf-1593818450293-40ef1caa15b3
> Request Header
:authority: mailsender-api.xxxxxx.xxx
:method: OPTIONS
:path: /sendmail
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,ko;q=0.8,la;q=0.7
access-control-request-headers: access-control-allow-credentials,access-control-allow-headers,access-control-allow-methods,content-type
access-control-request-method: POST
origin: https://mailsender-delta.vercel.app
referer: https://mailsender-delta.vercel.app/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
> General
Request URL: https://mailsender-api.xxxxxx.xxx/sendmail
Request Method: POST
Status Code: 405
Remote Address: 76.76.21.21:443
Referrer Policy: no-referrer-when-downgrade
> Response Headers
access-control-allow-credentials: true
access-control-allow-headers: Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Allow-Origin, Content-Type
access-control-allow-methods: POST, OPTIONS, HEAD
access-control-allow-origin: https://mailsender-delta.vercel.app
cache-control: s-maxage=0
content-type: application/json
date: Fri, 03 Jul 2020 23:20:50 GMT
server: Vercel
status: 405
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-vercel-cache: HIT
x-vercel-id: iad1::frndf-1593818450309-4f5547ab5464
> Request Headers
:authority: mailsender-api.xxxxxx.xxx
:method: POST
:path: /sendmail
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,ko;q=0.8,la;q=0.7
access-control-allow-credentials: true
access-control-allow-headers: X-Requested-With, Content-Type, Accept
access-control-allow-methods: *
content-length: 88
content-type: application/json
origin: https://mailsender-delta.xxxxxx.xxx
referer: https://mailsender-delta.xxxxxx.xxx/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
I faced the same problem. The solution is available in the doc of vercel: https://vercel.com/support/articles/how-to-enable-cors .
In your node.js backend, create a file vercel.json and put the code there.
{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Credentials", "value": "true" },
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
{ "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
]
}
]
}
It works for sure.
I'm trying to use the fetch API to send requests in my application, and if I get a 401 Unauthorized response, I want to read the value of the WWW-Authenticate response header. This works fine on Chrome, but on Firefox, I'm unable to see the WWW-Authenticate header, even though it's included in the Access-Control-Expose-Headers header of my response.
My code:
const api = async (endpoint, fetchOptions) => {
// fetchOptions:
// {
// "credentials": "same-origin",
// "method": "GET",
// "headers": {
// "Accept": "application/json",
// "Content-Type": "application/json"
// }
// }
const response = await fetch(endpoint, fetchOptions)
.catch(r => r)
.then(r => { r.headers.forEach(console.log.bind(console)); return r; });
// handle 401 errors
if (!response.status === 401 && response.headers.has('WWW-Authenticate')) {
const authenticate = response.headers.get('WWW-Authenticate');
const authEndpoint = authenticate.match(/authorization_endpoint="([^"]+)/i)[1];
window.location.href = authEndpoint;
return;
}
};
My request:
GET /api/login HTTP/1.1
Host: localhost:3001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:3000/
Content-Type: application/json
Origin: http://localhost:3000
Connection: keep-alive
My response:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json
Expires: -1
Server: Microsoft-IIS/10.0
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: WWW-Authenticate
WWW-Authenticate: Bearer realm="http://localhost:3001", authorization_endpoint="<oauth endpoint>"
Bearer
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcYXNjaW50ZXJuXFNvdXJjZVxSZXBvc1xQb3J0YWxcQVBJXFNhbXMuV2ViQXBpXGFwaVxsb2dpbg==?=
Date: Wed, 12 Jun 2019 13:37:08 GMT
Content-Length: 128
Console output:
no-cache cache-control
application/json content-type
-1 expires
no-cache pragma
Does anyone know why Firefox wouldn't be able to read that response header?
There's a known bug with multiple WWW-Authenticate response headers, you might be hitting that: https://bugzilla.mozilla.org/show_bug.cgi?id=1491010.
This is what my fetch code looks like
let getSummary = (year, month) => {
let url = baseUrl + "/rest/monthlySummaries/" +
localStorage.getItem("paUserId") + "/" + year + "/" + month;
let authHeaders = {
"Content-Type": "application/json",
"Accept": "application/json",
"Bearer": localStorage.getItem("paToken")
};
console.log("summary url:", url, ",headers:", authHeaders);
return fetch(url, {
method: "GET",
headers: authHeaders
});
};
Since this is GET request, browsers make preflight reqeusts using HTTP OPTIONS to make sure that they make indeed make HTTP GET requests. I log what call is made, I see
summary url: https://api.myapp.com/rest/monthlySummaries/userId/2017/4 ,headers: Object {Content-Type: "application/json", Accept: "application/json", Bearer: "41afa8432aaa411e48b6c1c637c77cb3:userId:84000000"}Accept: "application/json"Bearer: "41afa8432aaa411e48b6c1c637c77cb3:userId:84000000"Content-Type: "application/json"__proto__: Object
2VM50885:1 OPTIONS https://api.myapp.com/rest/monthlySummaries/cca6b151-cab4-4de2-81db-9a739a62ae88/2017/4 401 (Unauthorized)
While, when I do similar thing on curl, everything works
curl -v -X OPTIONS -H"BEARER:e3310afc4dcd68d80d56a83bddfd4a09:userId:564000000" "https://api.myapp.com/rest/monthlySummaries/userId/2017/4"
* Trying 52.23.254.96...
* Connected to api.myapp.com (52.23.254.96) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: DigiCert SHA2 High Assurance Server CA
* Server certificate: DigiCert High Assurance EV Root CA
> OPTIONS /rest/monthlySummaries/userId/2017/4 HTTP/1.1
> Host: api.myapp.com
> User-Agent: curl/7.43.0
> Accept: */*
> BEARER:e3310afc4dcd68d80d56a83bddfd4a09:userId:564000000
>
< HTTP/1.1 200 OK
< Date: Mon, 29 May 2017 23:21:11 GMT
< Server: WildFly/8
< X-Powered-By: Undertow/1
< Access-Control-Allow-Headers: origin, content-type, accept, authorization
< Allow: HEAD, GET, OPTIONS
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< Content-Type: text/plain
< Content-Length: 18
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
< Access-Control-Max-Age: 1209600
< Vary: Accept-Encoding
<
* Connection #0 to host api.myapp.com left intact
Why the behavior is so different? What am I missing in fetch?
UPDATE
My server enables CORS support
#Provider
public class CORSFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext containerRequestContext,
ContainerResponseContext containerResponseContext) throws IOException {
containerResponseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
containerResponseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
containerResponseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
containerResponseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
containerResponseContext.getHeaders().add("Access-Control-Max-Age", "1209600");
}
}
This can be seen in the response as well
See where you have configured
.add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
You haven't allowed the Bearer header, nor is it the correct way to pass a JWT.
You probably meant
"Authorization": `Bearer ${localStorage.getItem("paToken")}`
Sending Bearer when it isn't in the allowed headers list will fail the pre-flight validation.
I want to send some raw data to a subdomain of mine:
$.ajax({
url: "http://accounts.example.com:3000/me",
type: "PUT",
data: { wabo: "chabo" },
dataType: "json",
xhrFields: {
withCredentials: true
}
});
The browser now sends two requests:
OPTIONS to accounts.example.com:3000/me to check if CORS headers are valid
PUT to send data
The first one fails with HTTP 404 Not Found.
The CORS repsonse header looks valid:
HTTP/1.1 404 Not Found
X-Powered-By: Express
Access-Control-Allow-Origin: http://node.example.com:3000
Access-Control-Allow-Methods: HEAD, GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Requested-With, Origin, Accept
Access-Control-Allow-Credentials: true
Content-Type: text/plain
Set-Cookie: connect.sid=s%3Aru8njoU2ZAnoKL2W2w%2B0BHF7.%2Fe%2FQI5f6NKRWQvWlcYEkMG7HHSxxj0haFDBUID2g45A; Domain=.example.com; Path=/
Date: Sun, 04 Nov 2012 11:31:22 GMT
Connection: keep-alive
Transfer-Encoding: chunked
In app.js of my node environment I have:
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://node.example.com:3000');
res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Origin, Accept');
res.header('Access-Control-Allow-Credentials', 'true');
next();
});
and
var me = require('./me');
app.get('/me', loadUser, me.show);
app.put('/me', loadUser, me.update);
GETting data from the subdomain is no problem only sending
Any idea what I have forgotten?
Regards, bodo
Try this instead:
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://node.example.com:3000');
res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Origin, Accept');
res.header('Access-Control-Allow-Credentials', 'true');
if( req.method.toLowerCase() === "options" ) {
res.send( 200 );
}
else {
next();
}
});