Using Express and Passport JS on the backend we are currently able to login to the application, and access all of the API requests using postman.
However when we try and make API requests that require authentication on the React JS Web Application we get a 401 unauthorised error.
We've run logs from both the postman request and the web app request and both are passing the connect.sid cookie in the header.
My question is, how do I get the application authenticated and able to make API requests like postman can. I login to postman the same way I do using the web application but it doesn't authenticate the api requests.
Things I've tried:
manually setting the headers to allow cross origin requests
setting an Authorize bearer token
Specifying on the backend the origin of the front end, which only allows api calls to be made from the front end web server
The application is a ReactJS application, and I am making the API calls using Axios
I fixed this by passing withCredentials on login, this sends your user to the passport.js and authenticates the user.
You need to call withCredentials every time you make an API call though
Related
I am making an application with Nextjs and Nestjs for API. I want to support server-side rendering for certain pages with Nextjs. The authentication and user registrations need to be done on Nestjs. For now I am trying to do google oauth.
For requests from client side to API, I will have to send some access token along with the request to authorize the user. And for server-side authorization, I'll have to get this access token from the cookies and then send it in the request to the API. From what I have seen, access tokens last only 1 hour. So how can I do it in a way that lasts longer than 1 hour?
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!
I send a request to server to login and get cookie with token value with HTTP only tag after this action I can not access cookie value in my react app but I tested it in the postman app and i can see cookie in this app if I can see it in the postman app so I can see it in my app! what is different between them? Is There A Way To get HTTP only cookie in react app?
result from request response from server in postman
That is exactly the purpose of HttpOnly cookies.
The server sends the cookie along with the response, the browser stores it and sends it along with any request to the domain of this cookie. But the browser will prevent any code running on it to access it.
Why ?, this creates a secured way to store sensible information, such as authentication tokens, preventing any injected code in your page to access it.
https://www.owasp.org/index.php/HttpOnly
You can't have access to the httponly cookies in react or any javascript framework.
you see it in postman because in this case, postman acts like a browser and saves all of the cookies in itself then you can see them.
I am building a simple AngularJs web app that hits a REST Api built with Flask. From what I understand, there are a few ways to protect against CSRF, one of which is sending back a CSRF token when the user authenticates.
If I wanted to make my API available to both the Web Application and to users who want to use it as an API for development, would I need 2 endpoints for each endpoint that allows POST requests [one for the app that requires CSRF token + auth token and one for the developers that requires just an api access key]?
Not necessarily. Broadly, you have two options:
Proxy the REST API through whatever server-side container your web app is running in. Your web-app proxy can then implement the CSRF protection and insert the API-key into the API request.
Check the referrer header on all API requests. Although this requires that your Angular SPA and API share the same authentication mechanism, so you'd have to use something more sophisticated than an API key, like OAuth.
I am using Ping to authenticate users in a Angular/.NET Web API stack, utilizing WIF. WIF works out of the box by just putting in the correct configuration in web.config in a MVC or web Forms application. It intercepts any call to a page/controller requested and if no token available redirects to Ping for authentication.
Q1
In my stack that wont work as the web portion of this application is html/Angular. I could put the Ping configuration into the web api config file and then when angular calls the api, WIF will intercept it and (hopefully) redirect user to ping. But not sure if web api can do a http redirect. Also, pages that probably don't do a api call will load up just fine without authentication...
Q2
Lets say Issue 1 is resolved and user authenticates himself at ping, ping will need to send that assertion to the web api layer and not to html/Angular as it is a POST response. That is fine and web api will check the Claims object to get the user info. After which we will need to redirect the user to go back to the page he was trying to access, which now, app will not know anymore. Also how to achieve http redirection from web api.
Q3
Is there a way for Ping to post to a html/angular page?
Thanks for your help...
Due to the RESTful nature of APIs, they will not be able to do an HTTP Redirect. Even if they could it would be during an AJAX call and not affect the browser.
Out of the box WIF only supports the following protocols:
WS-Fed
WS-Trust
WS-Security
WS-SecurityPolicy
WS-Addressing
I suggest using the OAuth 2.0 Implicit Grant Type for the Angular/WebAPI portion.
That being said, the claims-based identity provided by WIF and OAuth are really complimentary. You could write an OAuth extension for WIF similair to the one referenced here: https://msdn.microsoft.com/en-us/library/azure/gg193416.aspx
This is what I imagine the flow would look like:
Angular app requests information from WIF protected API
API returns status code 401
Angular app performs redirect to Ping OAuth Authorization Endpoint
User Authenticates if they do not already have an existing session with the SSO IdP Server
Bearer token is returned to the Angular app
Bearer token is added to the Authorization header and sent to the API
WIF intercepts the request, extracts the Bearer token and calls the Ping OAuth Token Endpoint to validate the token
Ping returns a token that has the "Claims" information you are looking for, those claims are then injected into WIF.