Strapi CORS error although middleware is configured - node.js

I know there are similar questions out here, but nothing helped me so far. I'm getting a cors error in strapi v4.5.3 although I have configured it to allow the origin. Strapi doesn't seem to take the origins I'm using. My middleware.ts looks like this:
export default [
'strapi::errors',
'strapi::security',
{
name: 'strapi::cors',
config: {
enabled: true,
origin: process.env.CORS_ORIGINS
? process.env.CORS_ORIGINS.split(', ')
: '*',
credentials: true,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
headers: ['Content-Type', 'Authorization', 'Origin', 'Accept'],
keepHeaderOnError: true,
},
},
'strapi::poweredBy',
'strapi::logger',
'strapi::query',
'strapi::body',
'strapi::session',
'strapi::favicon',
'strapi::public',
]
with the following .env value:
CORS_ORIGINS=http://localhost:1337, http://localhost:6006, http://localhost:18082, https://portal-cms.example.de, https://portal-cms.example.bop
When I'm calling from localhost:6006 or localhost:18082 to localhost:1337 everything works fine. My dev server is available at https://portal-cms.example.de and when I try to call it from localhost:6006 or localhost:18082 I'm getting the following cors error:
Access to XMLHttpRequest at 'https://portal-cms.example.de/api/contact-infos?locale=en' from origin 'http://localhost:6006' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://portal-cms.example.bop' that is not equal to the supplied origin.
The request is made via axios from a vue component and looks like this:
console.log(await axios.get('https://portal-cms.example.de/api/contact-infos?locale=en'))
The response header has the value access-control-allow-origin: https://portal-cms.example.bop. I would have expected it to have the value that I configured in my middleware.ts. Am I understanding it wrong? and is there any way to make this error go away?

Related

Axios Unable to make request to IP address (Error: connect ECONNREFUSED)

I am trying to make a request to a 3rd party SOAP API, provided an IP address http://XXX.XXX.XXX.XXX:40871
I get the following error:
{
"success": false,
"error": "connect ECONNREFUSED XXX.XXX.XXX.XXX:40871",
"trace": "Error: connect ECONNREFUSED XXX.XXX.XXX.XXX:40871\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16)"
}
while testing locally I edited my hosts file and provided a host name to the IP
XXX.XXX.XXX.XXX my-host-name.com
then made a request to http://my-host-name.com:40871 and successfully got a response.
I can not do this in production since we are using heroku to deploy our app.
Our app is a middleware to make requests to the 3rd party API since they requires a static IP in its whitelist. we create a axios instance and recieve further options in the request body.
const agent = new HttpsProxyAgent(process.env.STATIC_URL!);
const baseOptions: AxiosRequestConfig = {
proxy: false,
httpsAgent: agent,
};
const instance = axios.create(baseOptions);
const response = await instance(req.body);
res.send({ success: true, response: response.data });
here is the request body:
{
"method": "POST",
"baseURL": "http://XXX.XXX.XXX.XXX:40871",
"url": "/IDORequestService/IDOWebService.asmx",
"data": {{xmlBody}},
"headers": {
"Content-type": "text/xml",
"SOAPAction": "http://frontstep.com/IDOWebService/CreateSessionToken",
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive"
}
}
Expected behavior: it should work with IP addresses
Environment:
Axios v0.27.2
https-proxy-agent: v5.0.1
Node.js v16.16.0
OS: Windows 11/Linux Mint 19.3
The problem was I did not have an httpAgent so it was not using the proxy for http requests, which is why the API server was probably refusing connection. Since it has the static IP in its whitelist and not our server IP.
const agent = new HttpsProxyAgent(process.env.STATIC_URL!);
const baseOptions: AxiosRequestConfig = {
proxy: false,
httpsAgent: agent,
httpAgent: agent,
};
const instance = axios.create(baseOptions);
const response = await instance(req.body);
res.send({ success: true, response: response.data });
adding the httpAgent fixed the issue.

NotFound error when calling flights date API

I have been using NodeJS library for querying the price of the chepeast flight for a route, for next 60 days. Even after switching to production environment, the API throws 404 error (details mentioned below) for some common routes like SFO to YYC.
Do let me know how I can resolve this.
NotFoundError {
response: Response {
headers: {
date: 'Tue, 19 Oct 2021 17:09:32 GMT',
'content-type': 'application/vnd.amadeus+json',
'content-length': '263',
connection: 'close',
'ama-internal-message-version': '14.1',
'ama-request-id': '00010UI9218IBV',
'ama-gateway-request-id': 'rrt-0b7b1036c139b8050-a-eu-4707-50043169-1',
'access-control-allow-headers': 'origin, x-requested-with, accept, Content-Type, Authorization',
'access-control-max-age': '3628800',
'access-control-allow-methods': '*',
server: 'Amadeus',
'access-control-allow-origin': '*'
},
statusCode: 404,
request: Request {
host: 'api.amadeus.com',
port: 443,
ssl: true,
scheme: 'https',
verb: 'GET',
path: '/v1/shopping/flight-dates',
params: [Object],
queryPath: '/v1/shopping/flight-dates?origin=SFO&destination=YYC&departureDate=2021-10-19%2C2021-12-
18&oneWay=true&viewBy=DATE',
bearerToken: '[REDACTED]',
clientVersion: '5.7.0',
languageVersion: '14.16.1',
appId: null,
appVersion: null,
headers: [Object]
},
body: '{"errors":[{"status":404,"code":6003,"title":"ITEM/DATA NOT FOUND OR DATA NOT EXISTING","detail":"No price result found"},{"status":404,"code":6003,"title" :"ITEM/DATA NOT FOUND OR DATA NOT EXISTING","detail":"No price results found for input combined criteria"}]}',
result: { errors: [Array] },
data: undefined,
parsed: true
},
description: [
{
status: 404,
code: 6003,
title: 'ITEM/DATA NOT FOUND OR DATA NOT EXISTING',
detail: 'No price result found'
},
{
status: 404,
code: 6003,
title: 'ITEM/DATA NOT FOUND OR DATA NOT EXISTING',
detail: 'No price results found for input combined criteria'
}
],
code: 'NotFoundError'
}
My code to query the data looks something like this:
const Amadeus = require("amadeus");
var client = new Amadeus({
hostname: "production",
clientId: FLIGHT_SEARCH_API_KEY,
clientSecret: FLIGHT_SEARCH_API_SECRET,
});
const response = await client.shopping.flightDates.get({
origin,
destination,
departureDate: `${currentDate},${lastDate}`,
oneWay: true,
viewBy: "DATE",
});
The Flight Inspiration Search & Flight Cheapest Date Search APIs are built on top of a pre-computed cache. The APIs compute every day the most trending options based on past searches and bookings and fill the cache, which means that the cache is dynamic. If you need to get access to a full inventory of Amadeus you need to use the live Flight Offers Search API.

Angular project with expressJS on backend doesn't work after adding SSL certificate to angular app

I have a web app that consists of 2 parts (Angular for the frontend on Hostgator and ExpressJS on the backend on AWS).
[My CORS configuration is enabled on the backend] everything is working fine until I had the SSL certificate from Hostgator, requests give me this error
ov {headers: Yb, status: 0, statusText: "Unknown Error", URL: (backendurl), ok: false, …}
error: ProgressEvent
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: XMLHttpRequest {__zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://smarketingbackend-env.eba-rkkgwymj.us-east-2.elasticbeanstalk.com/categories", __zone_symbol__loadfalse: Array(1), __zone_symbol__errorfalse: null, __zone_symbol__xhrScheduled: true, …}
defaultPrevented: false
eventPhase: 0
isTrusted: true
lengthComputable: false
loaded: 0
path: []
returnValue: true
srcElement: XMLHttpRequest {__zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "(backendurl)", __zone_symbol__loadfalse: Array(1), __zone_symbol__errorfalse: null, __zone_symbol__xhrScheduled: true, …}
target: XMLHttpRequest {__zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "(backendurl)", __zone_symbol__loadfalse: Array(1), __zone_symbol__errorfalse: null, __zone_symbol__xhrScheduled: true, …}
timeStamp: 36201.97499999995
total: 0
type: "error"
__proto__: ProgressEvent
headers: Yb
headers: Map(0) {}
lazyUpdate: null
normalizedNames: Map(0) {}
__proto__: Object
message: "Http failure response for (backendurl): 0 Unknown Error"
name: "HttpErrorResponse"
ok: false
status: 0
statusText: "Unknown Error"
url
I found A LOT of questions regarding this issue and most of the solutions are about CORS configuration. My CORS configuration is enabled, here it is...
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept , Authorization ,X-Auth-Token ,Access-Control-Allow-Headers ,affId "
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS"
);
next();
});
what is the issue here?
thanks in advance
pretty much just a guess, but in your URL "http://smarketingbackend-env.eba-rkkgwymj.us-east-2.elasticbeanstalk.com/categories" there is http instead of https. Can you try swapping that out?
Also you could use https://www.npmjs.com/package/cors as a cors middleware instead of providing your own - there might be some ceveats this plugins handles correctly.

GatsbyJS/ReactJS not proxying requests correctly

Here's some context. I have a ReactJS site, built with Gatsby. This site is entirely static and has no backend. I've recently been working on a backend integration, as I wanted to do some datavis stuff with the GitHub API. Anyway, I was working on building my own backend API with NodeJS, and then proxying the frontend requests (using the fetch API).
The frontend, during development, is at localhost:8000, and the backend at localhost:5000. This is my gatsby-config.js file. It has some other bits unrelated to this question, but the proxy bit is just at the bottom:
module.exports = {
siteMetadata: {
title: "Reece Mercer",
description: "Personal website"
},
plugins: [
'gatsby-plugin-react-helmet',
{
resolve: `gatsby-plugin-manifest`,
options: {
name: 'gatsby-starter-default',
short_name: 'Reece Mercer',
start_url: '/',
background_color: '#663399',
theme_color: '#663399',
display: 'minimal-ui',
icon: 'src/assets/images/website-icon.png', // This path is relative to the root of the site.
},
},
'gatsby-plugin-sass',
'gatsby-plugin-offline',
'gatsby-plugin-favicon',
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/blog_posts`,
name: 'blog_posts'
}
},
'gatsby-transformer-remark'
],
proxy: {
prefix: "/myRepoAPI",
url: "http://localhost:5000",
},
}
Essentially, any requests made from the frontend that are to /myRepoAPI/anything should be proxied away from the frontend, to the backend. I've used Postman to validate the backend, and this endpoint functions as it should.
Here is the fetch call I used in a frontend React component:
componentDidMount(){
fetch('/myRepoAPI/hello')
.then(res => console.log(res))
}
Now analysing that console log:
Response {type: "basic", url: "http://localhost:8000/myRepoAPI/hello", redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "basic"
url: "http://localhost:8000/myRepoAPI/hello"
__proto__: Response
The url value is at localhost:8000, not 5000. The proxy hasn't worked. I have tried different combinations of routes, trailing /'s, and even trying the advanced proxy method of developMiddleware. Nothing seems to get it working as it should.
Any help would be much appreciated!
Since Gatsby's internal development server (default at port 8000) handles the proxy, in the response object the url value will always be http://localhost:8000/... regardless whether the proxy's working or not.
You may have more clue when looking at the log from your local server at port 5000, see if the request from Gatsby is actually hitting that end; or log out the actual data you get from the request.

Authenticate UBER API through AngularJS 6 & Node

I am working on an application, in this application we consume UBER API. I am using NODE as backend and AngularJS 6 as frontend.
Workflow
In NODE part I have access authentication and other UBER API. i have tested through JQuery. It's working perfectly. But when I am trying to access with AngularJS 6. I am getting following error.
SyntaxError: Unexpected token h in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad (http://localhost:4200/vendor.js:11697:51) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:2743:31) at Object.onInvokeTask (http://localhost:4200/vendor.js:41155:33) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:2742:36) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:4200/polyfills.js:2510:47) at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (http://localhost:4200/polyfills.js:2818:34) at invokeTask (http://localhost:4200/polyfills.js:3862:14) at XMLHttpRequest.globalZoneAwareCallback (http://localhost:4200/polyfills.js:3888:17)
text: "https://login.uber.com/oauth/v2/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Flogin&scope=profile%20history%20places%20request&client_id=XXXXXXXXXXXXXXXXXXXXXXXXX"
__proto__: Object
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure during parsing for http://localhost:1455/api/login"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "http://localhost:1455/api/login"
__proto__: HttpResponseBase
Here is my code
NODE
app.get('/api/login', function(request, response) {
response.header('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
response.setHeader('Access-Control-Allow-Credentials', true);
var authURL=uber.getAuthorizeUrl(config.uber.scopes);
response.redirect(authURL);
});
AngularJS 6
data.service.ts
UberAuthenticate(){
return this.http.get('http://localhost:1455/api/login');
}
login.components.ts
export class LoginComponent implements OnInit {
constructor(private dataService: DataService) {
}
ngOnInit() {
this.dataService.UberAuthenticate().subscribe((response)=>{
console.log('response is ', response)
},(error) => {
console.log('error is ', error)
})
}
}
My Node application in running on PORT:1455, AngularJS PORT:4200 and callback url http://localhost:1455/api/callback.
I also set some configuration in proxy.config.json
{
"/api/*": {
"target": "http://localhost:1455",
"secure": false,
"changeOrigin": false,
"pathRewrite": {"^/api" : ""}
}
}
I haven't experience on NODE and AngularJS 6. I don't know where I am doing wrong?
Since the authorize endpoint is returning a plain text link, you need to specify it to angular in your service like this:
UberAuthenticate(){
return this.http.get('http://localhost:1455/api/login', { responseType: 'text' });
}
And in the NodeJS part, you will have to return the authorization url, the redirection has to be made in the frontend side.

Resources