keystonejs / keystone

The superpowered headless CMS for Node.js — built with GraphQL and React
https://keystonejs.com
MIT License
9.19k stars 1.15k forks source link

Cannot access admin page in product environment #2042

Closed qipt8 closed 4 years ago

qipt8 commented 4 years ago

Bug report

Cannot access admin page in product environment Project: demo-projects/meetup and custom with yarn create keystone-app ...

yarn build && yarn start

goto login page http://localhost:3000/admin/signin I tried with nuxt, next. The admin page is still accessible only in the dev environment

System information

Vultraz commented 4 years ago

This sounds like the issue where you cannot login if secure session cookies are enabled (the default in production) but not running the server over HTTPS.

ghost commented 4 years ago

Same Problem here

I am running the server over https:// and still cannot login. Even on the production. if I run yarn dev and go to url, i can login but not when I do yarn start. It will give me wrong password error if I put wrong credentials but right password will only refresh the page. Basically it knows the password is right but not moving forward. works wonderfully when running yarn dev. What can we do?

MadeByMike commented 4 years ago

Could someone having this issue please test the following configuration:

const { Keystone } = require('@keystonejs/keystone');

const keystone = new Keystone({
  secureCookies: false
  /*...rest of config */
});
ghost commented 4 years ago

Could someone having this issue please test the following configuration:

const { Keystone } = require('@keystonejs/keystone');

const keystone = new Keystone({
  secureCookies: false
  /*...rest of config */
});

This Worked. Thanks Mike... Are there any concerns for disabling secure cookies? I am only running over https.

MadeByMike commented 4 years ago

This is great however this is not my area of expertise so I will need get someone else on the team to have a look at it. I'm not yet sure whether there is a bug or if this is the expected behaviour of cookies on localhost with https

ghost commented 4 years ago

This happened even on production. The server was over nginx and http/2 with ssl installed. Let me know if you need any details or need to recreate scenario.

MadeByMike commented 4 years ago

Yeah I agree. This issue needs more investigation before we close it.

MadeByMike commented 4 years ago

It might be a simple environment config issue where we need the right combination of secureCookies and trust proxy: https://expressjs.com/en/guide/behind-proxies.html but I think it needs more investigation and/or documentation.

molomby commented 4 years ago

I was suspecting the same, @MadeByMike. Agree we should dig into it.

@sarunluitel1 any chance you could send the following details to the email in my profile?

ghost commented 4 years ago

@molomby I've sent the email. let me know if you have not received it.

nathsimpson commented 4 years ago

I'm having the same issue in a production environment too

MadeByMike commented 4 years ago

We need someone with relevant expertise to look at this in detail. @molomby not sure if this should be assigned to you but I'm also not sure who else could tackle this.

wesbos commented 4 years ago

Also getting this with Nginx reverse proxy. Any solutions out there, or does this need a lib change?

molomby commented 4 years ago

Will put some time aside next week to dig into this. @nathsimpson, might need your help to reproduce if you're around the office.

Vultraz commented 4 years ago

Possibly related? #2404

wesbos commented 4 years ago

Anyone able to take a look?

cozawariat commented 4 years ago

I'm having the same issue in production with https enabled, with custom express server example from documentation.

index.js

...
const keystone = new Keystone({
  name: PROJECT_NAME,
  adapter: new Adapter(),
  cookieSecret: process.env.COOKIE_SECRET,
  secureCookies: true,
  sessionStore: new MongoStore({ url: process.env.MONGO_URI }),
  onConnect: initializeData
})
...

app.js

require('dotenv').config()
const express = require('express')
const { keystone, apps } = require('./index.js')
keystone
  .prepare({ apps, dev: process.env.NODE_ENV !== 'production' })
  .then(async ({ middlewares }) => {
    await keystone.connect()
    const app = express()
    app.use(middlewares).listen(3000)
  })
Shinerising commented 4 years ago

My solution here: (And it works for me!)

  1. Enable Proxy Trust Middleware for Express (Edit your index.js of keystone)
module.exports = {
  keystone,
  apps: [
    new GraphQLApp(),
    new AdminUIApp(),
  ],
  configureExpress: app => {
    app.set('trust proxy', 1);
  }
};
  1. Set Proxy Headers (For me, the file to be edited is nginx.conf)
    location /admin/api {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Proto "https";
      proxy_set_header Host $host;
      proxy_pass http://app:3000; 
    }
  1. Set the Cookie Option as usual, then build your app and deploy it, and all is done!

Knowledge Page: https://expressjs.com/en/guide/behind-proxies.html

Shinerising commented 4 years ago

If anyone want to know how to set options to express instance:

https://www.keystonejs.com/guides/custom-server#you-might-not-need-a-custom-server-if

ropaolle commented 4 years ago

Could not login to a site behind a Nginx proxy either and tried all kind of different headers in the Nginx conf. And now it just works. Something not obvious was related to my error, like restarting browser or pc. Very strange.

The app is running behind jwilder/nginx-proxy.

In the end all I had to do was to set app.set('trust proxy', true).

My configuration looks like this

const keystone = new Keystone({
  name: '3CX-proben',
  adapter: new Adapter({ mongoUri: process.env.MONGO_URI }),
  onConnect: initialiseData,
  // Keystone build needs an access to mongo if there is an external session 
  // store https://github.com/keystonejs/keystone/issues/2350.
  sessionStore: !process.env.BUILD_STAGE ? new MongoStore({ url: process.env.MONGO_URI }) : null,
  cookieSecret: process.env.COOKIE_SECRET,
});

// Custom server
keystone
  .prepare({ apps, dev: process.env.NODE_ENV !== 'production' })
  .then(async ({ middlewares }) => {
    await keystone.connect();
    const app = express();
    app.set('trust proxy', true);
    app.use(middlewares).listen(3000);
  });
molomby commented 4 years ago

This looks like another case of the secure cookie/proxy issue (#1887). It's is a complex topic that cuts across Keystone's internals, project code, deployment config and browser behaviour. I've written up what I know here:

Keystone 5: Secure Cookies and Reverse Proxies

Quoting from the TL;DR -- you should ensure that...

molomby commented 4 years ago

Hey everyone, I'm going to close this as I believe the problem is resolved by my notes above. If you're still having issues (and have followed these steps) please open a new issue. Thanks!

leobar37 commented 3 years ago

Could someone having this issue please test the following configuration:

const { Keystone } = require('@keystonejs/keystone');

const keystone = new Keystone({
  secureCookies: false
  /*...rest of config */
});

This Worked. Thanks Mike... Are there any concerns for disabling secure cookies? I am only running over https.

that didn´t wor for me

michaelpaulcuccia commented 3 years ago

This worked for me, thanks @Shinerising

module.exports = {
  keystone,
  apps: [new GraphQLApp(),
  new AdminUIApp({
    name: PROJECT_NAME,
    enableDefaultRoute: true,
    authStrategy
  })
  ],
  //added for successful deployment
  configureExpress: app => {
    app.set('trust proxy', 1)
  }
};