使用Express.JS + Nginx设置Cookie时遇到问题

时间:2019-04-04 04:35:03

标签: javascript node.js express nginx express-session

我正在将前端与后端存储库分离。为此,我将服务器托管在家庭网络中的个人Raspberry Pi 3上。我的前端由Netlify托管。 我遇到了一个问题,尽管我可以在Postman中看到cookie设置,但无法在Express.Js的客户端上设置cookie。

我当前的设置如下:

FE (Netlify - example.com) -> Nginx (Reverse Proxy - api.example.com) -> Node.js (Express - listening for http)

我无法登录使用Express-Session进行会话的应用程序。我可以发布登录信息,但看不到响应上设置了cookie。话说回来,我正在Heroku上进行这项工作(FE + BE在同一个仓库中)

我已经尝试了很多事情来使它工作,但都失败了。

我尝试过的一些解决方案是:

  • app.set('信任代理',1)
  • express-session({proxy:true})
  • 将cookie域设置为.example.com
  • 为我的域启用了CORS
  • 将Axios设置为使用{ withCredentials: true }
  • 设置proxy_set_header X-Forwarded-Proto https;

NGinx配置

server {
        root /var/www/example-backend;
        server_name api.example.com;
        location / {
                proxy_pass http://127.0.0.1:3000;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Host $http_host;
                proxy_set_header X-NginX-Proxy true;
        }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

相关快递代码

const express = require('express');
const bodyParser = require('body-parser');
const logger = require('morgan');
const passport = require('passport');
const session = require('express-session');
const cors = require('cors');

const app = express();

const routes = require('./routes');
const server = require('./db');

app.use(logger('dev'));
app.use(cors({
  origin: 'https://example-frontend.netlify.com',
  credentials: true,

}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.set('trust proxy', 1)
app.use(
  session({
    secret: 'secrets',
    resave: false,
    saveUninitialized: true,
    cookie: { domain: '.example-frontend.netlify.com' }
  })
);


app.use(passport.initialize());
app.use(passport.session());

const Account = require('./models/account');

passport.use(Account.createStrategy());
passport.serializeUser(Account.serializeUser());
passport.deserializeUser(Account.deserializeUser());

app.use('/api', routes);

app.listen(3000, async () => {
  await server.start();
  console.log('HTTP running on port 3000');
});

routes.js

const express = require('express');
const router = express.Router();

router.get('/testCookie', (req, res) => {
  res.cookie('test', 'hi', { domain: 'example-frontend.netlify.com'})
  res.sendStatus(200);
});

相关前端代码

import axios from 'axios';

const API_ROOT =
  process.env.NODE_ENV === 'production'
    ? 'https://api.example.com/api'
    : '/api';
const API_RECIPE = `${API_ROOT}/recipe`;
const API_ACCOUNT = `${API_ROOT}/account`;

export const testCookie = () =>
  axios.get(`${API_ROOT}/testCookie`, { withCredentials: true });

我认为这与跨域cookie有关,但是我已经用尽了所有资源来了解可能出现的问题。我觉得这可能是在nginx级别,因为这是当前设置和Heroku设置之间唯一改变的部分。

任何帮助将不胜感激!

0 个答案:

没有答案