Angular doesn't send cookies on CORS - angularjs

I have an App Engine server hosting an AngularJS application that makes CORS requests to some Cloud Endpoints APIs on another App Engine server. As per the $http service documentation I have enabled it to send credentials in cross-domain requests by settinga default header:
$httpProvider.defaults.withCredentials = true;
The front-end server has an associated custom domain with SSL support, and makes requests via HTTPS (so that both the ends are basically HTTPS).
My goal is sending an authentication cookie to the backend in order to manage resource access authorization, but for some reason this cookie never gets sent.
I do see the cookie in the request when the two servers are running locally (frontend: http://localhost:8081, backend: http://localhost:8080), but not when they're deployed.
What am I missing there?
angular http Documetation i follwed

Try adding this header to your HTTP calls {'Content-Type': 'application/x-www-form-urlencoded'}

If I understand correctly, you want to send an authorization cookie over CORS to a different (sub)domain?
To do this, you need to permit CORS requests on the initial page load, use 'withCredentials' as you have detailed as well as have a cookie for the targeted cross domain call. If it's cross domain, you'll have to write the cookie in js code, if it's a sibling subdomain make sure the cookie domain starts with a dot .domain.com, and the cookie will then be shared across all subdomains of the domain.
Localhost can play havoc with this kind of testing because the domain relationships are different (i.e. Not sibling subdomains) - you can try using a local proxy to set up a scenario which maps subdomains to a loop back address.

Related

setting cookies with react-cookies to be read by DRF API

I want to set/remove a cookie on react web app when client switches between modes. I want the cookie to be sent with every request to the API which is using django rest framework, and use the value of the cookie to determine the kind of response. The web app and API are in different domains. I'm using react-cookie library to set the cookie which works fine on localhost but having issues setting it in other domains and will only let me use current domain for the cookie.
setCookie('is_test',true,{domain:document.domain.match(/.[^.]*\.[^.]*$/)?.[0]||document.domain,path:'/'})}
Thats the code I'm using to set the cookie, the regex is something I found to remove the subdomain (ex. www.testdomain.com converts to .testdomain.com) if there is any or just set the domain if its something like localhost
but when it is deployed to the actual domain the cookie doesn't get set. Also will the backend API read the cookie if the domain is set with the client domain or does it need to be the server domain that is used for the request. It doesn't let me use other domains outside of the current(client) domain

Serve React app and backend server from same domain

I have a react app serving from "https://www.domain1.com" and the backend is served on a different domain "https://www.domain2.com". Api requests made from domain1.com to domain2.com are not simple HTTP requests since we are adding an Authorization header in all the requests. This leads to CORS OPTIONS request being made further increasing the latency of the app by a heavy margin.
1. Is there any way I can merge the 2 domains ?
2. Can I avoid CORS OPTIONS preflight requests for these non-simple HTTP requests if I keep the domains separate ?
Yes, you can avoid CORS Policy option in your backend side not in your frontend. Where the API is developed, CORS Policy must be allowed there. After allowing you can call API which is serving from other domain.

Implement CSRF in ReactJS PWA with ExpressJS proxy to API backend

I have the following setup:
ReactJS PWA frontend application that uses service workers to cache the source code to the client.
ExpressJS Reverse Proxy which relays any request that would go to a backed API. This handles a login process and stores a token on the server and sends a session cookie to the client. The cookie is HtttpOnly, SameSite, Secure and signed. The proxy also checks if the connection is secure, referrer is in white list and exact match and same for the host.
Backend API is on a different server with OAuth login protection.
Express returns a server side rendered page on the first load then ReactJS hydrates that page and uses as an SPA. Every file afterwards is cached into the browser.
Every request that comes from the client app is handled with the same token as they are not user specific operations. User specific operations require e-mail and password to get a new unique token from the API.
My issue is:
An attacker could create a cookie and send it along with a curl request to the proxy. This would by pass my ReactJS app as both referrer and host can be faked.
I would like to find out how can is secure the connection between the ExpressJS proxy and the ReactJS PWA.
I was thinking about CSRF with csurf but that would not work. If the PWA is installed on a phone's as an app, then it would only access the Proxy when the request is sending. Therefore I cannot set the CSRF header.
If I was to add the CSRF token to the very first request when the client hits the server and the page is rendered with SSR, I would only set the token only once, which can be re used as many times as the attacker wants.
Is there a proper way to lock the proxy to the app somehow?
I cannot store anything in Local storage and I cannot hard code tokens into the source code of the app. (They are insecure options)
Thanks!

How do I disable AppEngine HTTP Endpoint

I see that my AppEngine endpoint is listening to both HTTP and HTTPS, how do I disable HTTP endpoint?
http://project-id.appspot.com - I want to disable this.
https://project-id.appspot.com
You cannot exactly disable it, but you can force a redirect to the HTTPS one.
If the endpoint runs in the standard environment you just need to set the secure: always config for the respective handlers in the app.yaml config file:
always
Requests for a URL that match this handler that do not use HTTPS are
automatically redirected to the HTTPS URL with the same path. Query
parameters are preserved for the redirect.
If it's in the flexible environment things are a bit more complicated, follow this thread: Force SSL on App Engine Flexible Environment Custom Runtime
If you want to deny requests over http (non-ssl) then check value for X-Forwarded-Proto header and respond with error if its value it http.
This header is added by GAE. https://cloud.google.com/appengine/docs/standard/java-gen2/reference/request-response-headers
X-Forwarded-Proto [http | https] Shows http or https based on the
protocol the client used to connect to your application.
The Google Cloud Load Balancer terminates all https connections, and
then forwards traffic to App Engine instances over http. For example,
if a user requests access to your site via
https://PROJECT_ID.REGION_ID.r.appspot.com, the X- Forwarded-Proto
header value is https.

How to persist authenticated state in a sailsJS backend app when requests are from another domain?

I have an architecture where I'm using sailsJS (custom node.js implementation) as my api server and an angular front end server. Each app is being served from different domains.
How can I maintain an authenticated session in the sailsJS api app between requests?
Sails has an integrated req.session object for maintaining sessions but it doesn't seem to be working out of the box when the client is being served from another domain.
You need to check two things when doing cross-origin requests from your front-end app to your Sails app:
Make sure your Sails app has CORS enabled; this will ensure that the browser doesn't block the requests for security reasons
Make sure the withCredentials flag is set in your AJAX request; this will ensure that your cookie is sent to Sails and your session is maintained.
With Restangular, you can set withCredentials to be used on all requests by default using setDefaultHttpFields; see this answer for details.

Resources