Cookies only set with web security disabled? (Node.js/Express.js app) - node.js

I'm using node/express to make a pure backend api. My front-end (angular.js) is hosted on a separate server. I have a few lines of middleware for every request to allow CORS.
If I start chrome with -args --disable-web-security flags, everything works great!
However if I start it normally, cookies seem to not be getting set in the browser, and therefore sessions on the node side aren't kicking in. This is the same for safari/mobile safari/etc.
I've tried browser options such as "accept all cookies"/"never block cookies". I thought maybe browsers don't like localhost but this is the same behavior on localhost and on actual hosted domains.
The flow is:
I login and the session is set with an id, on success the frontend is directed to the next page. This works, and I console logged req.session.id and it's correct.
On the next page a request is sent, the node server is configured to use the id in the session for this request. With safari/mobile safari/chrome the req.session.id is suddenly empty. With chrome -security disabled, the req.session.id is still correct and behaves just like it should.

please refer to this answer that covers cross-domain cookies and session: Using Express and Node, how to maintain a Session across subdomains/hostheaders

Related

Understanding how cookie is set on the browser

I'm using express-session to initialize a session and save the cookie. But the process of how the cookie is saved browser side is abstracted away and something of a black box to me, it just happens automatically. Can anyone point to a resource that explains how the client takes the cookie from the response and saves it in local storage? My front facing stack is composed of react, nextjs and urql client.
When you use express-session to initialize a session and save the cookie on the server, the client automatically receives the cookie in the response from the server and saves it in the local storage. This happens because the browser automatically includes the cookie in the request headers for any subsequent requests to the same domain, and the server uses the cookie to identify the user's session.
The process of how the cookie is saved in the local storage and included in the request headers is part of the underlying mechanics of the HTTP protocol and is handled automatically by the browser. It is not something that you need to worry about or configure when using express-session.
If you want to learn more about how cookies work in general, you can check out the following resources:
The official documentation for cookies on the Mozilla Developer
Network: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
A tutorial on cookies from the W3Schools website:
https://www.w3schools.com/js/js_cookies.asp

How to make an Angular 5 + Node app with CAS authentication?

I'm currently trying to build an app that needs the user to authenticate with CAS (Centrale Authentication Service) to use it. I'm using Angular 5 for the front-end and Node.js for the back-end.
To authenticate the user on the server side I'm using a module called 'r-cas-authentication' which creates an express-session when the user is authenticated. The fact is I don't know how to check on the Angular side if the user is authenticated and otherwise redirect him on the CAS authentication page.
Do you know how I could do that?
Thanks!
You don't need to deal with this on angular side. Just have the Node server redirect the unauthenticated users to a login page, always. Browser sets the session headers, and your Node server will see there's no auth and send a redirect. The r-cas-authentication module mentions the bounce and bounce_redirect options in the docs, this will further streamline the process.
Your node instance will serve the login page.:
app.get('/login', (req, res) => res.sendFile('path/to/login.html'));
Additionally, your assets (frontend scripts, css, images, etc) are (usually) free to have:
app.get('/assets', express.static(pathToStaticDirectory));
Also, you have authentication endpoint:
app.get( '/authenticate', cas.bounce_redirect );
Next, it needs to serve the Angular app. It will, however, require a cas session here. We target '/home' but it can be another path like '/' or whatever have you.
app.get('/home', cas.bounce, express.static(pathToAngularAppDirectory);
Finally, you will likely have REST API endpoints that you want protected:
app.use('/api', cas.block, appRoutes);
Now, here's what happens. Request comes infrom the browser. It hits the '/home' route. Since the browser is on it'S first visit, there's no authentication headers set. It will hit the cas.bounce() block and get redirected to /login route. Once it goes there, it gets served login.html*.
You enter your login data there and hit Login button - the page gets submitted, and cas middleware authenticates the user - sets the session data and all to browser. Browser will cary these around with it (note I say browser, not Angular). It also redirects the user back to '/home' page.
Now your browser has the session info, so it gets a pass on the route, gets served the Angular files, the app starts normally. All is cool.
There is one more case you might wanna handle from Angular.
Let's say your session expired. And the browser was left open or something. The user revisits the page - all cool, cas.bounce will redirect the user back to login form.
But what if the user simply clicks "refresh" in your app? Then Angular's HttpClient gets a 401 response (as per node module docs). You can have a simple http interceptor that does a window.location.reload() or similar (basically a full page reload, not client-side navigation), and on a page reload, your app get's caught into cas.bounce because it's trying to reload /home unauthenticated.

Node Express, handle Session Cookie with multiple domains

i've a node app that use a session stored into a cookie.
That app are invoked fron different domain, so i need to store the cookie with the right domain.
I followed this solution
It works but i have a little problem.
I start the app and open my browser the app work fine, the cookie are stored rightly.
Well if restart the app (forever restart) and reload the windows in the browser the app doesn't work, the session are not recognize, but i see the cookie stored as resource in my browser.
If delete the cookie and reload my window the app work fine, the session works rightly and so the app and i see the cookie on my resource.
it works rightly or not?
Any help are appreciated

Accessing node/locomotive.js server on cloud9 gets redirect to signin.html

I am running my web server written in node/locomotive.js on cloud9 terminal. When I try to access it from a client program such as curl, it gets redirected to
https://c9.io/signin.html?redirect=http%3A%2F%2Fchekofvgameserver-c9-linzhp.c9.io%2F
That makes it impossible for any client program to test the server. Access it from a browser works fine, because the browser remembers my cloud9 credentials.
Is there a way to skip the signin page of cloud9?
The problem is that your project is probably a private project. In order to guarantee that only authorized people have access to your running the Cloud9 proxy will intercept calls to your application and check the permissions. If it doesn't find a valid session cookie you will be redirected to the login page. When you use Cloud9 to develop an API server the client will obviously not have that session cookie and fail in the way you described above.
I see two options to work around this:
Use a public workspace instead of a private one
Run curl from inside Cloud9. You can simply open a second terminal and instead of the hostname just use $IP:$PORT to talk to the server

IE/IIS integrated authentication problem

In IIS I've got:
http://myserver/myapplication
http://myserver/reports
The reports app is reporting services in fact which uses windows authentication. myapplication is an asp.net application that uses forms authentication.
The server is outside the company domain. If I access the reports first and type in the user and password(local credentials created on the server) when prompted I can access the reports page, no problems. If then I go straight to my application's login page and try to login, the login page refreshes without doing anything. This always happen in IE 6. In IE 7 it happens intermittently. Does not happen in Firefox or if Fiddler is running in the background which seems to fix the problem on the fly.
I used wireshark to see what's going on and found that IE 6 send the windows authentication token obtained from the reports app to myapp. That was the only difference between IE and Firefox. IIS seems to freak out and simply interpret my POST to the login page as a GET and return.
If I add windows authentication to myapplication in IIS everything seems to work fine with any browser.
Why is this happening? A bug in IE or am I missing something?
It's sorta a bug in IE, and sorta a bug in the design of NTLM/Negotiate (aka Integrated) authentication over HTTP.
NTLM/Negotiate are connection-oriented auth protocols, which HTTP wasn't really designed for. As a result, when you require this auth mechanism for one page on your server, IE will typically assume that other pages on the server have the same requirement.
Furthermore, for performance and security reasons, if IE expects a Negotiate/NTLM challenge for a given POST request, then it will first send a 0 byte POST, expecting the server to return a HTTP/401 challenge to which it will authenticate and then properly send the POST body.
However, in your case, the folder which doesn't require Integrated auth gets the 0 byte POST and says "Hrm, weird, a 0 byte post. Okay, HTTP/200, here's the page as if you'd used GET."
Because IE never gets the 401 challenge it expects, it never actually sends the POST body.
(Fiddler may confuse you a bit due to how HTTP connection reuse works).
The workaround is to ensure that if you're using Integrated auth on the host, use it everywhere.

Resources