API call work on nodejs but not on angular / client side js - node.js

I'm trying to access STREAK Api using angular. When i'm sending the request to Streak i'm getting a CORS Policy error but when trying to access the same request using Node.js i'm getting the response.
So my question is, why is that happening? both the client and the server are hosted on localhost

For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts.
This doesn't have anything to do with angular or any other javascript framework.
You can read more about CORS here

Related

(failed)net::ERR_CERT_AUTHORITY_INVALID when using fetch api in Chrome extension service worker

We are migrating our chrome extension from Manifest V2 to V3. In this process we removed JQuery AJAX requests and started using fetch API in the background page for sending REST API requests to the server. When sending the requests, the first 2 to 3 requests will get a response but after that the requests are failing. It is throwing (failed)net::ERR_CERT_COMMON_NAME_INVALID error.
The API requests works fine when using the Jquery AJAX calls.
API calls in the network tab
Details about the server :
The server is installed in my machine only. I am accessing the server through localhost. When we access the server for the first time in a browser a warning page will be shown. We have to click proceed to access the website. Normally the Jquery AJAX requests works fine once we click the proceed option.
Server warning page
I tried giving different header options in the fetch API, but the result was still same.
How do I resolve this fetch API error ?

How to fetch api in local host i.e localhost/9563 in react js

When I build my react js it does not show any fetch API and gave me an error (get/playlist) When I developed the react js web I give proxy in the package.json file. I know that it works only on the development side but how to fetch API when I build the website and that present to the client with fetch API can I use express js?
An app that I fetch is in localhost/9563 React js run in localhost/3000
The easiest way is to use the proxy from react:
https://create-react-app.dev/docs/proxying-api-requests-in-development/ - which you might already do based on your question.
Can you maybe share your package.json? I suspect you might have misconfigured it.
Alternatively if you do not wish to use the proxy:
Make sure to enable CORS in your Express application, due to different ports between frontend and backend, the same-origin policy of your browser does not apply. So the request will not be run.
You can use the CORS middleware for it:
https://expressjs.com/en/resources/middleware/cors.html
Once your Express backend allows CORS, your request should run just fine.
As a side note: Server-side cookies will NOT be sent this way, as many browsers do not send cookies if the port is different. If you need server-side cookies to be sent along in your fetch request, you need to have 3 things in place:
CORS is enabled in backend
CORS Allow Credentials header is set in backend
in the frontend fetch is called using {withCredentials: true} option
Both backend and frontend run under the same port (especially important on localhost), so you may need nginx for proxying to backend/frontend in that case.

Can a REST API works as a PROXY for CORS issues?

My problem is as follows :
I'm developping a web application with Angular. Angular application runs on the client's browser. In its logic, my application needs data from other-domain.com.
I can't use directly XMLHttpRequest() because of CORS policy problems. (The web server other-domain.com producing data is not my domain and cannot add 'Control-Access-Allow-Origins')
So instead of having :
Angular ===>> other-domain.com (forbidden because of CORS)
I'm creating a REST API that will get data from other-domain.com and wraps this data with header 'Access-Control-Allow-Origin' : '*' before sending to client's Angular.
So my workflow becomes :
Angular ==>> my API server ==>> other-domain.com (allowed because request for other-domain does not execute on the browser)
Do you think my idea works well forevery request (GET, POST, adding cookies header) ? In that case the API I'm developping acts as a proxy, right ?
Thank you
Short answer: yes. In fact, there's packages and sites out there that will do this for you.
But I think another question is why you have the need to circumvent CORS restrictions. After all, it is working as intended and there's a reason for its existence in the first place.
If you have a backend already, can you add an endpoint where your backend will make the call to the other domain, and leave the browser to communicate only within your domain?
If you're only doing RESTful GETs and an opaque request (no credentials, no cookies, etc.) will suit your needs, you could also just use the fetch api with {mode: 'no-cors'}; however, you'd need to 'circumvent' the HttpClient to do so and you'd need a polyfill if you need to support IE.

Setting access control header in Node JS for receiving in Angular frontend

I am building a MEAN stack app where I have Node on the back end and Angular on the front-end. I am working on user authentication where I have a login page in my Angular. The login info is set to the Node back end where using bcryptjs I compare the password with the encrypted password stored in the MongoDB database. I then create a token using JSON web tokens that I send by to Angular by setting in the header. I got it working on my computer. But I had to do this.
In my NodeJS express app, in development mode I have my Node server running on port 3000 and my Angular server running on 4200. I had to set:
res.setHeader('Access-Control-Expose-Headers', 'x-auth');
To allow Angular to access the x-auth header which contains the token using:
let token = response.headers.get('x-auth')
Without setting the expose header on NodeJS, the header does not show up on the Angular app.
And to set the header in the response, in the NodeJS method that handles authentication, I use the usual:
res.setHeader('x-auth', token);
So, this is my question:
How will this work when deployed on say Heroku? When the client tried to login, will I need to set ('Access-Control-Expose-Headers', 'x-auth') so that client can receive the token that NodeJS server sends back? Since, these are two separate domains? Will I need to set this header on production also since I do so only on development now. I tried running the entire app in production mode on my computer and it runs without the need for the header, but I am accessing it from the same domain so there is no CORS issue.
I also tried sending the login POST requests to the NodeJS server through POSTMAN. And I was getting back the x-auth token with or without the expose header. So how does the POSTMAN requests differ from the requests sent by Angular?

Client (angular 2) authentication , passport google as provider in server (node.js)

I've been looking a lot for an answer here.
I have a nodejs server with some REST endpoint. Each endpoint has isLoggedIn middleware so I can authenticate the user by it's email.
The client runs on port 4200 and the server runs on port 3113.
What I would like is basically to have my client redirect to Google's consent screen if not authenticated. Since the ports are different I get:
XMLHttpRequest cannot load https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_ur…d=604408607019-ha937stehe6s3nk7ea892rviihrq5n4s.apps.googleusercontent.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
Now, what haven't I tried... :)
I tried using the CLI proxy feature (it's a webpack configuration) and to forward all /api requests to the server.
I have added headers to the server but then I realized that it's Google who's sending this error and not my server.
I saw lots of posts here that are related. The best solution that I've seen so far was to put a login button and just put the call to auth in href, because I cannot do ajax calls between domains.
Is this really the best solution? Isn't it any other way to authenticate from the client while the authentication code is running on the server?
I even added all the relevant ports for the api and the callback call to Google developer console.
BTW, all works well when a client is served from the same port.
Thanks.
A little late, but I have your solution. I just solved this myself and I stumbled upon your question when I was looking for a solution. You will not be able to call a .http.get() request from the google auth itself through Angular. What you're going to have to do is do a redirect window.location.href = 'your-express-uri-here' and then when you authenticate, you can create a new Express route, and get the user data from that route itself. for example you can call .http.get('your-profile') from angular and then in your express route have your route be router.get('your-profile/', (req, res) =>{ res.send(req.user) } This works, because with Passport you use a cookie and when you sign in you are authenticated already, and you have access to the data from the user. You don't need to have a GET request from the login to get the user data, just a GET request from your node app once you have already logged in using Google+Passport. For this to work, you do have to run Angular in proxy to your node app.

Resources