MERN 应用程序未存储会话

时间:2021-03-09 00:42:51

标签: reactjs mongodb express cors express-session

我的 MERN 应用程序无法在浏览器上存储会话。后端由 Heroku 托管,客户端由 Vercel 托管。当我切换到 localhost 时,它按预期工作,但在部署时,它无法存储任何会话。如果我尝试登录用户,它将通过身份验证,但不会在我的浏览器上存储会话。

我收到此错误:

    Access to XMLHttpRequest at 'https://myapp-backend.herokuapp.com/user' from origin 'https://myapp-client.vercel.app' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

这是我所拥有的。

Server.js:

const url = process.env.MONGO_DB_URL

mongoose.connect(url, {
  useNewUrlParser: true,
  useCreateIndex: true,
  useUnifiedTopology: true,
  useFindAndModify: false,
})

const db = mongoose.connection
db.on('error', console.error.bind(console, 'connection error'))
db.once('open', () => {
  console.log('connected to mongo database')
})

const app = express()

app.set('views', path.join(__dirname, 'views'))

app.use(
  mongoSanitize({
    replaceWith: '_',
  })
)
app.use(helmet())
app.use(express.json())
app.use(
  cors({
    origin: ['http://192.168.1.14:3000', 'https://myapp-client.vercel.app'],
    credentials: true,
  })
)
app.use(express.static(path.join(__dirname, 'public')))

// express session middleware

const store = MongoStore.create({
  mongoUrl: url,
  secret: process.env.MONGO_SECRET,
  touchAfter: 24 * 60 * 60,
})

store.on('error', err => {
  console.log(err)
})

app.use(
  session({
    store,
    name: 'rfts',
    secret: process.env.MONGO_SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: {
      expires: Date.now() + 1000 * 60 * 60 * 24 * 3,
      maxAge: 1000 * 60 * 60 * 24 * 3,
      httpOnly: true,
      secure: true,
  })
)

app.use(cookieParser(process.env.COOKIE_SECRET))

// passport middleware
app.use(passport.initialize())
app.use(passport.session())
passport.use(new LocalStrategy(User.authenticate()))
passport.serializeUser(User.serializeUser())
passport.deserializeUser(User.deserializeUser())

const PORT = process.env.PORT || 3001

app.listen(PORT, () => {
  console.log(`listening on port ${PORT}`)
})

在客户端,我用它来调用服务器:

import axios from 'axios'

const macUrl = 'http://192.168.1.14:3001'
const localUrl = 'http://localhost:3001'
const herokuUrl = 'https://myapp-backend.herokuapp.com'

const axiosCall = axios.create({
  baseURL: herokuUrl,
  withCredentials: true,
})

export default axiosCall

任何建议将不胜感激!

1 个答案:

答案 0 :(得分:1)

我没有使用 heroku 部署的经验。但根据我的经验,原始 url 应该与 cors[] 数组的第一个元素匹配。 请在后端代码中试试这个:

app.use(cors({ origin: ['https://myapp-client.vercel.app', 'http://192.168.1.14:3000'], credentials: true, methods: ['GET', 'PUT', 'POST', 'OPTIONS', 'DELETE'] }));

origin:array 中元素的顺序会根据应用所在的位置而改变:localhost 或 live site。

相关问题