Getting error when using mimik's first-edge-microservice - javascript

I am working on a code to allow your microservice to retrieve your network’sEdge Cloud Engine linkLocal clustering information as in the mimik's page but after making the HTTP call from curl i am getting the following issue.
starter-microservice\build>curl -i -H "Authorization: Bearer "
http://localhost:8083/localDevices
HTTP/1.1 404 Not Found
Cache-Control: no-cache, no-store, must-revalidate, private, max-age=0
Pragma: no-cache
Expires: 0
Content-Type: text/plain; charset=utf-8
Date: Thu, 14 Jan 2021 07:36:33 GMT
Connection: close
Error 404: Not Found
Not Found

Is the microservice you are trying to call developed by you or is it the starter-microservice found here on mimik github ?
If its your own microservice then you need to call the right endpoint. One of the reasons you're getting 404 is because the endpoint cannot be found. You also need to provide the JWT token you received during edge association using OAuth Tool. You have to put the token right after the words 'Authorization: Bearer YOUR-JWT-TOKEN' in your curl command.
Please follow these tutorials in the order they appear:
https://developer.mimik.com/development-setup/
Once you've finished this please copy the "edge Access Token” this is the
JWT token mentioned earlier.
If you have your own microservice you would like to deploy then you need to follow the instructions here: https://developer.mimik.com/deploying-edge-microservice/ if not then clone this repo from mimik Github and follow the instructions in the README.md

Related

Unable to get CORS working despite "access-control-allow-origin => *" shown to be working

I have uploaded a Reactjs build to a subdomain (a web hosting service), but most of the Axios.get API requests are causing CORS errors. It does not seem to be the usual problem of allow-origin because that tests to be working.
I created .htaccess and put it in the subdomain root folder with the following code
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
which I confirmed working with the online test tool that gave this result:
"HTTP/1.0 200 OK =>
Connection => close
content-type => text/html
last-modified => Mon, 08 Aug 2022 03:52:36 GMT
accept-ranges => bytes
content-length => 644
date => Mon, 08 Aug 2022 02:39:20 GMT
server => LiteSpeed
access-control-allow-origin => *
alt-svc => h3=":443"; ma=2592000, h3-29=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000, quic=":443"; ma=2592000; v="43,46""
when I test my URL with test-cors.org it also shows to be working:
Sending GET request to https://subdomain.mysite.com
Fired XHR event: loadstart
Fired XHR event: readystatechange
Fired XHR event: readystatechange
Fired XHR event: progress
Fired XHR event: readystatechange
Fired XHR event: load
XHR status: 200
XHR status text: OK
XHR exposed response headers:
content-length: 287
content-type: text/html
last-modified: Mon, 08 Aug 2022 03:52:36 GMT
Fired XHR event: loadend
but my site produces this error in the browser inspector:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
https://query2.finance.yahoo.com/v8/finance/chart/MYM=F?region=US&lang=en-US&includePrePost=&interval=15m&range=2d.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status
code: 200.
I can only think that the server cache needs clearing, as I found a lot of people with problems similar suddenly find it working after a few days, but I need to know if it is something I am doing wrong rather than wait days for a cache refresh.
Thanks to #jaromanda-x in the comments I resolved this by approaching it differently.
I cloned a CORS ANYWHERE proxy server on Heroku and added the subsequent URL created onto the front of my axios.get requests for my React build. After it tested working, I whitelisted it with only my domain address so that the public facing CORS proxy server would not be abused.
The steps were as follows:
create a free account with Heroku and download their CLI and login from there. I then cloned CORS ANYWHERE to my local machine from that CLI
git clone https://github.com/Rob--W/cors-anywhere
cd cors-anywhere
then created an app on heroku with
heroku create
it makes it with a random name you can then change via the platform or in the CLI.
Once that was done I deployed it from the CLI with
git push heroku master
This created a public address I was able to put on the front of my axios.get URL requests in React so they now looked like this
axios.get('https://mycorsproxyapp.herokuapp.com/https://query2.finance.yahoo.com/v8/finance/chart/MYM=F?region=US&lang=en-US&includePrePost=&interval=15m&range=2d')
That tested working fine on my live React build site, so the final part was to lock it down to only my site, and to limit the risk of my own site abusing it accidentally, I limited the rate to 60 per minute. This was done from the local Heroku CLI or in the platform settings.
heroku config:set -a mycorsproxyapp CORSANYWHERE_WHITELIST=https://myreactsite.com
heroku config:set -a mycorsproxyapp CORSANYWHERE_RATELIMIT="60 1"

How to render 404 page when a user is unauthenticated in nextjs

I am using next-auth to authenticate users. When I navigate to api routes that don't exist on my NextJS server, I get a 404 response and an error page. I would like to emulate this behaviour when an unauthenticated user navigates to one of my api routes. My current test route looks something like this:
// api/test.js
import { getSession } from 'next-auth/client'
export default async (req, res) => {
const session = await getSession({ req });
if (session) {
// Signed in
res.json(JSON.stringify(session, null, 2));
} else {
// Not Signed in
res.status(404);
}
res.end();
}
Unfortunately, this results in a blank page. Ideally, I would like if an unauthenticated user could not tell the difference between a page that doesn't exist and a blocked api route. I also noticed that when I curl a non-existing route, e.g. curl -i http://localhost:3000/api, I get the following response (as well as all of the html for the error page):
HTTP/1.1 404 Not Found
Cache-Control: no-store, must-revalidate
X-Powered-By: Next.js
Content-Type: text/html; charset=utf-8
Content-Length: 2427
Vary: Accept-Encoding
Date: Thu, 20 May 2021 10:45:45 GMT
Connection: keep-alive
Keep-Alive: timeout=5
When I run curl -i http://localhost:3000/api/test to hit the above code I get the following response:
HTTP/1.1 404 Not Found
Date: Thu, 20 May 2021 10:44:57 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked
How do I modify the response when the user is not authenticated to look (and return the same headers) as the default NextJS 404 error response?

Error when GET HTTPS from REST API in Angular

I have an Angular app running which uses an external api to get countries ISOs.
This API uses https and it's giving me an error.
The thing is: when I use a proxy in my angular local environment, mapping /iso-api/ to the real url it works ok.
"/iso-api/*": {
"target": "https://www...",
"pathRewrite": { "^/iso-api": "" },
"secure": false,
"changeOrigin": true,
"logLevel": "debug"
}
But I want this to work in production, so I want to use the real url.
In my server I am returning the Access-Control-Allow-Origin: * header already.
I've tried to run the angular server with ssl (as the external api uses https), but I receive the same error.
I know a solution would be to implement the proxy in the server, but I believe this should not be done and there may be a way to retrieve this data from the frontend.
Help please.
Response
This is the network error in Chrome:
In Firefox, the request ends with 200 OK and returns data, but CORS error is thrown and I cannot access the data from the app: CORS header 'Access-Control-Allow-Origin' missing
General
Request URL: https://www...
Referrer Policy: no-referrer-when-downgrade
Request headers
:method: GET
:scheme: https
accept: application/json, text/plain, */*
accept-encoding: gzip, deflate, br
accept-language: es-ES,es;q=0.9,en;q=0.8
origin: http://localhost:4200
referer: http://localhost:4200/app/login
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
Response headers
accept-ranges: bytes
cache-control: max-age=0
content-encoding: gzip
content-language: en-US
content-length: 68356
content-type: application/json
date: Mon, 27 Apr 2020 14:49:30 GMT
expires: Mon, 27 Apr 2020 14:49:30 GMT
referrer-policy: strict-origin-when-cross-origin
server-timing: cdn-cache; desc=HIT
server-timing: edge; dur=1
server-timing: ACTT;dur=0,ACRTT;dur=88
set-cookie: ... expires=Mon, 27 Apr 2020 16:49:30 GMT; max-age=7200; path=/; domain=...; HttpOnly
set-cookie: ... Domain=...; Path=/; Expires=Mon, 27 Apr 2020 18:49:30 GMT; Max-Age=14400; HttpOnly
set-cookie: ... Domain=...; Path=/; Expires=Tue, 27 Apr 2021 14:49:30 GMT; Max-Age=31536000; Secure
status: 200
vary: Accept-Encoding
UPDATE
Angular service code
import { HttpClient } from '#angular/common/http';
...
constructor(
private _http: HttpClient,
private _errorUtil: ErrorUtilService,
private _converter: StoreConverter
) {}
...
getCountries(): Observable<CountryWithLanguages[]> {
return this._http.get<GetStoresResponse>(API.storeUrl).pipe(
catchError(this._errorUtil.handle),
map(result => result.stores),
switchMap(stores => stores),
filter(this._isActiveStore),
map(store => this._converter.toView(store)),
toArray()
);
}
To serve the app I use angular dev server, I do not add the 'Access-Control-Allow-Origin' header manually but, in the browser, I see that it is being added.
angular.json
"serve": {
"builder": "#angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "push-web-app:build",
"proxyConfig": "src/proxy-local.conf.json"
},
}
You can't request a resource from another domain. This would be a security hole. You can read more here: Same-origin policy
Sending Access-Control-Allow-Origin: * from your server won't give you access to the aforementioned API. The provider of this API needs to give you permission to access the API, you can't give yourself this permission.
The error you posted states that the Access-Control-Allow-Origin header is missing. It means that the API isn't sending this header.
There might be two reasons why this API isn't sending Access-Control-Allow-Origin header.
A misconfiguration on the side of this API. In this case you have to ask the provider of this API to fix this issue.
The API provider is restricting access to the API on purpose. In this case you have to ask the provider of this API to give you access from your domain.
You can also proxy the request through your server. The core difference when using proxy is that your server reads the resource from the API and not the client browser. See David's response on how to configure proxy with nginx.
You cannot bypass CORS browser side. If you are not able to modify the server side, your only solution is to use a proxy.
For development purposes, you can use angular's built-in proxy server, but not for production.
Here is a basic nginx config to do this
server {
listen 80;
server_name yourdomain.com; #domain where your angular code is deployed
location /iso-api{
RewriteRule ^/iso-api/(.*)$ /$1 break;
proxy_pass https://thirdpartyapidomain.com; #url of the API you are trying to access
}
location
{
#Your normal angular location
#try_files ...
}
}
This will redirects requests like
http://yourdomain.com/iso-api/countriesList to https://thirdpartyapidomain.com/countriesList;
Since now client and server API calls are on the same domain, you should not have CORS issues
Use this site to resolve the CORS error:
https://cors-anywhere.herokuapp.com/
Use Exemple
https://cors-anywhere.herokuapp.com/https://freegeoip.app/json
this._http.get('https://cors-anywhere.herokuapp.com/https://freegeoip.app/json')
It's just a workaround but it works. Use it even just to understand if the error is related to CORS or something else.
Try the .get call with option withCredentials: true:
return this._http.get<GetStoresResponse>(API.storeUrl, { withCredentials: true }).pipe();
...and/or making sure your browsers are up to date.

Serving pre-flight request using ExpressJS

I created a simple route in express using the code below.
const express = require("express");
const app = express();
app.get('/route1', (req, res) => {
res.send({ data: "Route 1" });
});
app.listen(3000);
When I run curl -X GET http://localhost:3000/route1, I am getting {"data":"Route 1"} as response.
However, I tried running curl -X OPTIONS http://localhost:3000/route1 to simulate a CORS pre-flight request. I received GET,HEAD as the response.
I was not able to find any documentation supporting this behaviour. Why did the above route respond to OPTIONS request?
(NOTE: I haven't used any other packages like CORS)
EDIT
Based on Quentin's answer, I tried issuing another OPTIONS request with relevant headers and with display headers flag in curl.
curl -i -X OPTIONS http://localhost:3000/route1 \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: content-type,x-requested-with'
HTTP/1.1 200 OK
X-Powered-By: Express
Allow: GET,HEAD
Content-Type: text/html; charset=utf-8
Content-Length: 8
ETag: W/"8-ZRAf8oNBS3Bjb/SU2GYZCmbtmXg"
Date: Wed, 03 Jul 2019 11:14:07 GMT
Connection: keep-alive
GET,HEAD
OPTIONS is a standard HTTP method with standard behaviour that has built-in support in Express.
The CORS spec layers additional semantics over the top of a regular OPTIONS request.
curl -X OPTIONS http://localhost:3000/route1 makes an OPTIONS request, but it isn't simulating a prefight request (as it is missing a bunch of request headers that are required by the CORS specification). The response you get to that request doesn't include any CORS response headers either.
Re edit:
I tried issuing another OPTIONS request with relevant headers
You missed out the Origin header, but as you can see, since you didn't set up CORS support in the Express app, the response still doesn't include any CORS response headers.

Cookies not saved when using npm request library

I have a local environment and I'm trying to login to a service. I'm using the 'request' library in the client and Express and express-session in the service.
I'm using Chrome and when I login to the service I get the following response headers:
FROM: http://app.dev:3000
TO: http://app.dev:4000/login/local
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://app.dev:3000
Vary: Origin, X-HTTP-Method-Override
Access-Control-Allow-Credentials: true
Content-Type: application/json; charset=utf-8
Content-Length: 304
ETag: W/"130-fdQBs605dSVTeEqXEuXrvdcQTLk"
set-cookie: auth=TOKEN; Path=/; Expires=Sun, 25 Jun 2017 01:48:41 GMT
Date: Sat, 24 Jun 2017 13:48:41 GMT
Connection: keep-alive
When I login with Postman the cookie gets stored correctly. Subsequent requests through Postman include the cookie and everything is working fine.
But doing the same request with the npm request library it won't save the cookie and subsequent requests to the backend do not include cookies. Example request to the service after logging in. No cookie sent.
The request library documentation doesn't mention the withCredentials option but setting it to true fixes the issue. The cookie now gets saved and is being sent on subsequent requests.
const requestBase = request.defaults({
baseUrl: 'http://app.dev:4000/',
withCredentials: true,
});

Categories

Resources