Shopify / shopify-express

“Get up and running quickly with Express.js and the Shopify API.”
MIT License
137 stars 87 forks source link

Express-session throws error in production build #77

Open kpatel1989 opened 6 years ago

kpatel1989 commented 6 years ago

This is error I get when I try to run my shopify app in production build.

Warning: connect.session() MemoryStore is not designed for a production environment, as it will leak memory, and will not scale past a single process.

I am not able to use session in production build. I tried to put this only on dev environment but then shopify auth doesnt work. It says

"Session not present on request, please install a session middleware."

preconfxsd commented 6 years ago

I'm having the same problem, did you find any solution @kpatel1989 ?

kpatel1989 commented 6 years ago

I made a few modifications to the default flow. I implemented my own Strategy class which returns getShop and storeShop function, I dont use session. I save the token into the db and fetch it from there. I also have my own version of withShop middleware function which looks into the DB for the acessToken.

theonlydaleking commented 6 years ago

For anyone else, this will happen when you are trying to deploy to Heroku with the default session setup (using memoryStore)

the same as above I ended up writing my own strategy class to handle this.

richardbonneau commented 5 years ago

For anyone else, this will happen when you are trying to deploy to Heroku with the default session setup (using memoryStore)

the same as above I ended up writing my own strategy class to handle this.

Could you share your code? Or an example?

theonlydaleking commented 5 years ago

@richardbonneau which issue are you seeing? The Memory store one? Or the "Session not present on request, please install a session middleware?"

If its Session not present, this isn't code - it's more than likely you don't have redis set up on your dev environment.

richardbonneau commented 5 years ago

@richardbonneau which issue are you seeing? The Memory store one? Or the "Session not present on request, please install a session middleware?"

If its Session not present, this isn't code - it's more than likely you don't have redis set up on your dev environment.

Thank you for your answer theonlydaleking. I see redis in my dev environment. Didn't you mention writing your own strategy class to fix the problem? What would that look like? Thank you

kpatel1989 commented 5 years ago

@richardbonneau To write your own strategy class. Use the existing Strategy class and modify the getShop and storeShop functions. Basically, these functions pick the shop from the session but that is not necessary. You can use a different storage, for eg. a database. In my case I save them and fetch then from a mysql database. thats how I validate each request. I know its too many calls to the DB but I use serverless architecture and this is best for me as of now.

theonlydaleking commented 5 years ago

@richardbonneau if you want to use MySql like @kpatel1989 I think there's already a strategy for that in the repo. That should be all you need

Nisthar commented 5 years ago

@kpatel1989 I tried it. It makes the app very slow to load.

kpatel1989 commented 5 years ago

@Nisthar : If your db is remote than yes it will consume some network time. Use a lightweight DB locally on the node server to manage session.

Nisthar commented 5 years ago

@kpatel1989 ok, I currently use postgres for both session and db storage. I am using custom strategy. I think its making the app very slow to load. is there a way to use postgres as db storage and redis for sessions?

kpatel1989 commented 5 years ago

@Nisthar Ya sure, you can but the default session behaviour of this package is designed to work on dev env. you might have to make modifications to make it work on prod too. its not difficult. Make your own Memory Strategy and use a session module like Redis.

richardbonneau commented 5 years ago

To anyone out there with the same issue, this ended up working for me : https://github.com/Shopify/shopify-node-app/issues/77#issuecomment-354744926

I added the two lines of codes mentioned in the comment and then signed up for a free plan on Redis to go. I then added the following Config Vars on Heroku:

NPM_CONFIG_PRODUCTION: false YARN_PRODUCTION: false REDIS_URL: (You have to copy the full url given on the redis to go dashboard)

Then I added new commands to my package.json scripts (i decided to force heroku to use yarn instead of npm) and move a lot of the devDependencies to dependencies. Here's what mine look like for reference:

{ "name": "shopify-node-app", "version": "0.0.0", "private": true, "scripts": { "prod": "yarn run clean && yarn run build && NODE_ENV=production yarn run go", "dev": "NODE_ENV=development yarn run go", "go": "node ./bin/www", "build": "NODE_ENV=production webpack --config ./config/webpack.config.js --progress --profile --colors", "clean": "rm -rf ./assets && mkdir ./assets", "pretty": "prettier --single-quote --trailing-comma es5 --write {client,bin,config,server}{/*,/*/}.js", "precommit": "yarn run pretty", "start": "yarn run clean && yarn run build && NODE_ENV=production yarn run go", "heroku-prebuild": "yarn install --production=false", "postinstall": "NODE_ENV=production webpack --config ./config/webpack.config.js" }, "engines": { "node": "^8.9.1" }, "browsers": [ "last 3 chrome versions", "last 3 firefox versions", "last 2 versions", "safari >= 8", "ios >= 8", "ie >= 11", "explorermobile >= 11", "android >= 4.4" ], "dependencies": { "@shopify/polaris": "^2.3.1", "@shopify/shopify-express": "^1.0.0-alpha.7", "autoprefixer": "^7.1.1", "chalk": "^1.1.3", "connect-redis": "^3.3.0", "cross-env": "^5.1.3", "debug": "~2.6.3", "dotenv": "^4.0.0", "ejs": "~2.5.6", "es6-promise-pool": "^2.5.0", "express": "~4.15.2", "express-session": "^1.15.3", "isomorphic-fetch": "^2.2.1", "knex": "^0.13.0", "morgan": "~1.8.1", "nodemon": "^1.17.1", "react": "^16.4.0", "react-dom": "^16.4.0", "react-object-inspector": "^0.2.1", "react-redux": "^5.0.5", "redis": "^2.7.1", "redux": "^3.6.0", "redux-logger": "^3.0.6", "redux-thunk": "^2.2.0", "shopify-api-node": "^2.11.0", "sqlite3": "^3.1.9", "style-loader": "^0.18.2", "url": "^0.11.0", "webpack": "^2.6.1", "webpack-hot-middleware": "^2.18.0", "webpack-middleware": "^1.5.1", "react-hot-loader": "^3.0.0-beta.7", "postcss-loader": "^2.0.6", "babel-core": "^6.25.0", "babel-loader": "^7.0.0", "babel-plugin-transform-object-rest-spread": "^6.23.0", "babel-plugin-transform-class-properties": "^6.24.1", "babel-preset-env": "^1.5.2", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "css-loader": "^0.28.4", "webpack-dev-middleware": "^2.0.4" }, "devDependencies": { "eslint": "3.19.0", "eslint-plugin-prettier": "^2.1.2", "global": "^4.3.2", "prettier": "^1.5.2", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" } }

And that's it! It worked!