Reputation: 1078
Working from some time on a sails web application.
So far overcome all issues by hard reading, trial and error.
Recently had to install the app for a close beta test on the client's ec2 free trial instance where it works just fine in development mode.
The app is behind a nginx proxy which listens on the 80 port and redirects to http://server_IP:1337.
CORS and CSRF are enabled, allowOrigins and onlyAllowOrigins are set to the server IP, web domain and localhost in production.js and, security.js and sockets.js.
But when switching to production mode all API requests, except GET, give 403 forbidden.
Tried everything I could find on Google, it simply doesn't work on production but it completely works on development.
If anyone could share a shred of light on this will be greatly appreciated.
EDIT:
Running the app with debug silly, showed this:
A socket is being allowed to connect, but the session could not be loaded. Creating an empty, one-time session to use for the life of this socket connection. This log often shows up because a client socket from a previous lift or another Sails app is trying to reconnect (e.g. from an open browser tab), but the session indicated by its cookie no longer exists-- because either this app is not currently using a persistent session store like Redis, or the session entry has been removed from the session store (e.g. by a scheduled job or because it expired naturally). Details: Error: Session could not be loaded. at Immediate._onImmediate (/var/www/allscubashops.com/node_modules/sails/lib/hooks/session/index.js:543:42) at processImmediate (internal/timers.js:445:19)
Then I have deleted the old browser cookie and got this:
Could not fetch session, since connecting socket has no cookie in its handshake. Generated a one-time-use cookie: sails.sid=s%3APlHbdXvOZRo5yNlKPdFKkaPgVTNaNN8i.DwZzwHPhb1%2Fs9Am49lRxRTFjRqUzGO8UN90uC7rlLHs and saved it on the socket handshake.
This means the socket started off with an empty session, i.e. (req.session === {}) That "anonymous" session will only last until the socket is disconnected. To work around this, make sure the socket sends a
cookie
header or query param when it initially connects. (This usually arises due to using a non-browser client such as a native iOS/Android app, React Native, a Node.js script, or some other connected device. It can also arise when attempting to connect a cross-origin socket in the browser, particularly for Safari users. To work around this, either supply a cookie manually, or ignore this message and use an approach other than sessions-- e.g. an auth token.)
Also no new cookie was set.
The apparent conclusion is that somehow in production mode something is wrong with setting the session.
EDIT 2:
The latest find is that if I run the app without nginx proxy, I do not have the forbidden API requests issue but I still have the one related to the session not being created.
I am sure the nginx proxy settins are OK but now I am thinking of implementing the redis way to store sessions instead of the default memory one and see what happens
EDIT 3:
I have implemented the Redis sessions which works both for dev and prod modes.
Still same situation, the ec2 instance without nginx proxy works in production mode while the same files (git replicated) on the ec2 instance with nginx proxy doesn't work in production mode (API requests 403 forbidden) but works great in development mode.
The X-CSRF token is sent, screenshot The sails error message I get in production (besides the network 403 forbidden error for all requests except GET) is:
A socket is being allowed to connect, but the session could not be loaded. Creating an empty, one-time session to use for the life of this socket connection. This log often shows up because a client socket from a previous lift or another Sails app is trying to reconnect (e.g. from an open browser tab), but the session indicated by its cookie no longer exists-- because either this app is not currently using a persistent session store like Redis, or the session entry has been removed from the session store (e.g. by a scheduled job or because it expired naturally). Details: Error: Session could not be loaded. at /var/www/example.com/node_modules/sails/lib/hooks/session/index.js:543:42 at Command.callback (/var/www/example.com/node_modules/@sailshq/connect-redis/lib/connect-redis.js:148:25) at normal_reply (/var/www/example.com/node_modules/machinepack-redis/node_modules/redis/index.js:714:21) at RedisClient.return_reply (/var/www/example.com/node_modules/machinepack-redis/node_modules/redis/index.js:816:9) at JavascriptRedisParser.returnReply (/var/www/example.com/node_modules/machinepack-redis/node_modules/redis/index.js:188:18) at JavascriptRedisParser.execute (/var/www/example.com/node_modules/redis-parser/lib/parser.js:574:12) at Socket. (/var/www/example.com/node_modules/machinepack-redis/node_modules/redis/index.js:267:27) at Socket.emit (events.js:193:13) at addChunk (_stream_readable.js:296:12) at readableAddChunk (_stream_readable.js:277:11) at Socket.Readable.push (_stream_readable.js:232:10) at TCP.onStreamRead (internal/stream_base_commons.js:150:17)
Therefore I assume that the sockets connect but the session is not created.
Redis works OK, I see sessions in it for when in development.
Upvotes: 1
Views: 831
Reputation: 31
Have you exposed the csrf endpoint and are you making a call to that endpoint first, to get a token, before making further requests? This tipped me up once.
Upvotes: 1